Решил хранить изображения в двух разных форматах: одно, основное, сохраняется с оригинальным размером (до 2Мб) и расширением (.jpg, .png или .webp); второе - миниатюрная версия первого, для отображения в каталогах, сохраняется в другую директорию (скажем, thumbnail), всегда в формате webp, а также с уменьшенным размером.
Манипуляции с изображениями решил проводить средствами GD, основная идея такая:
- после сохранения оригинала, получаю экземпляр изображения imagecreatefromjpeg()
- с tempnam создаю временный файл и пишу туда изображение с помощью imagewebp(), третий параметр функции позволяет управлять качеством изображения
- далее в цикле делаю то же самое, уменьшая значение для качества до тех пор, пока размер файла не станет меньше предварительно заданного
Код:
// $image: GdImage
// $initialQuantity - начальное значение для качества сохраняемого изображения
// $targetFileSize - фиксированное значение размера (в байтах), файлы будут уменьшаться, пока это значение не будет достигнуто
// $thumbnailPath - куда будет сохранен результирующий файл
$tempPath = tempnam(sys_get_temp_dir(), 'compressed_image');
imagewebp($image, $tempPath, $initialQuality);
//проверяем размер сохраненного изображения:
while ($targetFileSize <= filesize($tempPath) && $initialQuality > 10) {
$initialQuality -= 5;
imagewebp($image, $tempPath, $initialQuality);
}
//На выходе из цикла сохраняем файл в директорию с миниатюрами
copy($tempPath, $thumbnailPath);
imagedestroy($image);
unlink($tempPath);
Пошагово прошёлся с Xdebug по итерациям цикла - всё работает, с первоначального размера в 49698 за три итерации файл уменьшается до значения ниже 30 Кб, соответственно из цикла выходим с размером в ~32 Кб
Но когда поставил точку остановы за циклом, после его работы на выходе получил те же изначальные 49698 (цикл завершился из-за второго условия, $initialQuality уменьшилось до 10), т.е. несмотря на постоянное уменьшение значения качества сохраняемого файла размер остался тем же самым
С чем может быть связано? И почему при пошаговой итерации с Xdebug получаются корректные значения?
Может, есть решение проще - по сути, задача только в том, чтобы ужать файл до фиксированного размера (в байтах) и сохранить в расширении .webp