Как создать скрипт для автоматического ресайза изображений на PHP

Автоматическое изменение размера изображений на PHP помогает подготовить фотографии для сайта, интернет-магазина или галереи без ручной обработки каждого файла. Скрипт может принимать исходную картинку, уменьшать её до заданной ширины, сохранять пропорции и записывать готовый результат в отдельную папку.

Для решения задачи обычно используют встроенную библиотеку GD или расширение Imagick. GD доступна на большинстве хостингов и подходит для стандартных операций: ресайза, обрезки, конвертации JPEG, PNG и WebP. Imagick предлагает больше возможностей, особенно при работе с цветом, качеством и большими файлами.

Подготовка PHP-среды и файлов

Перед началом работы нужно проверить, подключено ли расширение GD. Временно создайте файл info.php с таким содержимым:

<?php
phpinfo();

Откройте его в браузере и найдите раздел GD. Если он отсутствует, активируйте расширение в настройках PHP или обратитесь к панели управления хостингом. На локальном сервере Windows нужная строка обычно находится в файле php.ini и выглядит как extension=gd.

Скрипт должен знать, где лежит исходное изображение и куда сохранить копию. Лучше не перезаписывать оригинал: исходник может понадобиться для повторной обработки с другим размером или качеством. Для безопасности также стоит разрешать только известные форматы и проверять реальный MIME-тип файла, а не доверять его расширению.

В простом сценарии можно обрабатывать изображения из папки uploads, а уменьшенные версии хранить в uploads/resized. Если каталог назначения ещё не существует, PHP создаст его с помощью mkdir(). Права на запись должны быть настроены так, чтобы веб-сервер мог создавать файлы, но посторонние пользователи не получили доступ к загрузке исполняемых скриптов.

Расчёт новых пропорций изображения

Ресайз изображения начинается с определения его исходной ширины и высоты. Для этого применяется функция getimagesize(). Если известна максимальная ширина, новая высота рассчитывается по формуле: исходная высота умножается на новую ширину и делится на исходную ширину.

Например, фотография размером 4000×3000 пикселей при ограничении ширины 1200 пикселей станет изображением 1200×900. Пропорции сохранятся, а картинка не будет растянута по вертикали. Если исходное изображение уже меньше заданного размера, его обычно не увеличивают, чтобы не ухудшать резкость.

$size = getimagesize($source);
$sourceWidth = $size[0];
$sourceHeight = $size[1];

$maxWidth = 1200;

if ($sourceWidth > $maxWidth) {
    $newWidth = $maxWidth;
    $newHeight = (int) round($sourceHeight * $newWidth / $sourceWidth);
} else {
    $newWidth = $sourceWidth;
    $newHeight = $sourceHeight;
}

Для превью с фиксированными шириной и высотой понадобится дополнительная логика. Можно вписать фотографию в заданную область с сохранением пропорций или выполнить центральную обрезку. Первый вариант не обрезает содержимое, а второй создаёт одинаковые карточки для каталога. Практические детали создания миниатюр через GD разобраны в материале создание превью изображений.

Полный пример скрипта на GD

Ниже приведён универсальный вариант для JPEG, PNG и WebP. Он загружает исходный файл, создаёт пустое изображение нужного размера, переносит в него содержимое и сохраняет результат. Функция imagecopyresampled() выполняет качественное масштабирование с интерполяцией пикселей.

<?php

$source = __DIR__ . '/uploads/photo.jpg';
$destination = __DIR__ . '/uploads/resized/photo.webp';
$maxWidth = 1200;

if (!is_file($source)) {
    exit('Исходный файл не найден');
}

$info = getimagesize($source);

if ($info === false) {
    exit('Файл не является изображением');
}

$sourceWidth = $info[0];
$sourceHeight = $info[1];
$mime = $info['mime'];

if ($sourceWidth > $maxWidth) {
    $newWidth = $maxWidth;
    $newHeight = (int) round($sourceHeight * $newWidth / $sourceWidth);
} else {
    $newWidth = $sourceWidth;
    $newHeight = $sourceHeight;
}

switch ($mime) {
    case 'image/jpeg':
        $sourceImage = imagecreatefromjpeg($source);
        break;
    case 'image/png':
        $sourceImage = imagecreatefrompng($source);
        break;
    case 'image/webp':
        $sourceImage = imagecreatefromwebp($source);
        break;
    default:
        exit('Формат не поддерживается');
}

$result = imagecreatetruecolor($newWidth, $newHeight);
imagealphablending($result, false);
imagesavealpha($result, true);

$transparent = imagecolorallocatealpha($result, 0, 0, 0, 127);
imagefill($result, 0, 0, $transparent);

imagecopyresampled(
    $result,
    $sourceImage,
    0,
    0,
    0,
    0,
    $newWidth,
    $newHeight,
    $sourceWidth,
    $sourceHeight
);

imagewebp($result, $destination, 82);

imagedestroy($sourceImage);
imagedestroy($result);

echo 'Изображение обработано';

Пример сохраняет результат в WebP, поскольку этот формат часто уменьшает размер файла при сопоставимом визуальном качестве. Для JPEG вместо imagewebp() используется imagejpeg($result, $destination, 82), а для PNG — imagepng(). У PNG параметр качества работает иначе: в нём используется уровень сжатия от 0 до 9.

Прозрачность особенно важна при обработке PNG. Вызовы imagealphablending() и imagesavealpha() помогают сохранить альфа-канал. Для фотографий с JPEG они не обязательны. После завершения работы изображения нужно удалить из памяти функцией imagedestroy(), иначе при массовой обработке больших файлов процесс может завершиться из-за нехватки памяти.

Обработка загрузки и защита

Если файл поступает через HTML-форму, проверяйте ошибки загрузки, размер и тип. Ограничение размера защищает сервер от случайно отправленных многосотмегабайтных файлов. Проверка MIME через finfo_file() надёжнее, чем анализ имени вроде photo.jpg.

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['image']['tmp_name']);
finfo_close($finfo);

$allowed = [
    'image/jpeg',
    'image/png',
    'image/webp'
];

if (!in_array($mime, $allowed, true)) {
    exit('Недопустимый тип файла');
}

if ($_FILES['image']['size'] > 10 * 1024 * 1024) {
    exit('Файл слишком большой');
}

Имя результата лучше генерировать самостоятельно: например, с помощью hash('sha256', uniqid('', true)). Это снижает риск перезаписи существующего файла и исключает опасные символы в имени. Каталог загрузок не должен позволять выполнять PHP-файлы. На сервере Apache для этого можно добавить правила, запрещающие выполнение скриптов в папке с пользовательскими файлами.

При пакетной обработке используйте список файлов из каталога и запускайте ресайз по одному. После каждого изображения освобождайте память. Если фотографии поступают из формы, полезно дополнительно создавать несколько вариантов: большую версию для страницы, среднюю для списка и маленькую миниатюру. Такой подход уменьшает время загрузки сайта и экономит мобильный трафик.

GD или Imagick для автоматического ресайза

GD хорошо подходит для небольшого сайта, стандартных фотографий и простого PHP-скрипта. Она легко вызывается без сложной конфигурации и содержит всё необходимое для изменения размеров, создания миниатюр и конвертации распространённых форматов. Ограничение GD проявляется при обработке очень больших файлов и сложных цветовых профилей.

Imagick является PHP-интерфейсом к ImageMagick. Его выбирают, когда требуется пакетная обработка, работа с TIFF, PDF, анимацией, профилями цвета или расширенными фильтрами. Однако расширение может быть недоступно на бюджетном хостинге, а неправильные настройки ImageMagick требуют отдельного внимания с точки зрения безопасности.

Для публикации изображений важен и сам контекст материала. Например, если сайт содержит визуальные карточки о повседневном уходе, можно заранее подготовить одинаковые превью для статьи материал об уходе за кожей. Скрипт при этом остаётся универсальным: ему неважно, изображена ли косметика, фотография товара или иллюстрация к записи.

Критерий GD Imagick
Доступность на хостинге Обычно высокая Зависит от тарифа и настроек
Базовый ресайз Подходит Подходит
Поддержка сложных форматов Ограниченная Широкая
Потребление ресурсов Умеренное Может быть выше
Сложность настройки Низкая Средняя
Пакетная обработка Возможна Удобна для больших объёмов
Работа с цветом и профилями Ограниченная Расширенная

Для WordPress такой обработчик можно подключить к событию загрузки изображения или запускать отдельной командой для уже существующих файлов. При большом количестве медиа лучше использовать очередь, чтобы не перегружать сервер во время одного веб-запроса. Перед публикацией проверьте размеры, качество, прозрачность и корректность имён файлов.

Сохраните исходники, настройте разрешённые форматы и протестируйте скрипт на портретных, альбомных и квадратных изображениях. После этого автоматический ресайз можно встроить в загрузку файлов, галерею или пакетную оптимизацию медиатеки, сократив объём изображений без ручной обработки.

Иконка пользователя в серых тонах

Настройка Windows

Доступ к скрытым параметрам конфигурации, отключение телеметрии, работа с диспетчером задач и тонкая настройка меню «Пуск» в стиле Windows XP для Windows 7.

Иконка браузера в серо-синих тонах

Веб-браузеры

Скрытые страницы конфигурации в Firefox, Chrome и Opera, быстрый текстовый редактор прямо в браузере, эффект Lightbox JS для изображений и настройка внешнего вида Firefox.

Иконка папки в нейтральных серых тонах

WordPress и блоги

Выполнение PHP-кода в текстовых виджетах, диагностика времени загрузки разделов страницы, правильная очистка блога и условная загрузка виджетов социальных сетей.

Изометрический 3D-рендер: светлый веб-сайт с серо-голубым заголовком, парящий над чистой белой поверхностью Изометрический 3D-рендер: тёмно-серая иконка социального букмаркинга на светлом фоне

Обратная связь

Есть вопрос или предложение по темам блога? Напишите — автор на связи.