Функция imagecopyresampled полезна для создания уменьшенных изображений или изменения размера изображения при сохранении соотношения сторон:
$fn = $_FILES['data']['tmp_name']; $size = getimagesize($fn); $width = $size[0]; $height = $size[1]; $ratio = $width / $height; if ($ratio > 1 && $size[0] > 500) { $width = 500; $height = 500 / $ratio; } else { if ($ratio <= 1 && $size[1] > 500) { $width = 500 * $ratio; $height = 500; }} $src = imagecreatefromstring(file_get_contents($fn)); $dst = imagecreatetruecolor($width, $height); imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); imagedestroy($src); imagejpeg($dst, 'test.jpg'); imagedestroy($dst);
Как я могу выбрать алгоритм изменения размера, используемый PHP?
Примечание: как указано в этом вопросе , установка imagesetinterpolation($dst, IMG_BILINEAR_FIXED);
или такие вещи, похоже, не работают.
Согласно тестам, которые я сделал (на другом языке), «билинейное изменение размера» иногда дает лучший результат, чем бикубический, а иногда и наоборот (зависит от того, уменьшилось ли оно или увеличилось).
Альтернативой является imagescale()
, которая позволяет указать алгоритм интерполяции как параметр:
imagescale($image, $new_width, $new_height, $algorithm);
В соответствии с документом $algorithm
может быть:
Один из
IMG_NEAREST_NEIGHBOUR
,IMG_BILINEAR_FIXED
,IMG_BICUBIC
,IMG_BICUBIC_FIXED
или что-нибудь еще (будет использовать два прохода).
Тест в PHP 7.0.15 (сравнение хэша файла) показывает, что BICUBIC и BICUBIC_FIXED приводят к другому изображению, в то время как BILINEAR_FIXED и NEAREST_NEIGHBOUR приводят к тому же изображению.
imagecopyresampled
базируется / частично LibGD, просматривая исходный код LibGD, вы можете четко видеть его реализацию , а также документация не является двусмысленной в отношении используемого алгоритма, поскольку указано, что:
Если область источника и получателя отличается по размеру, область будет изменена с использованием билинейной интерполяции для изображений с изображением truecolor и интерполяции ближайшего соседа для изображений палитры.
Итак, как вы можете выбрать алгоритм изменения размера, используемый PHP?
Если вы настаиваете / должны использовать функции LibGD, вы не можете (если вы не перекомпилируете PHP с помощью вилки LibGD, вы код для этого вопроса).
Однако, если вы можете использовать другую библиотеку манипуляции с изображениями, вы можете просто использовать ту, которая использует другой алгоритм для изменения размера, например Imagick, кажется, предлагает широкий спектр интерполяций, но так как документация довольно беззвучна, здесь константы необходимо использовать метод Imagick::setImageInterpolateMethod(int $)
:
const INTERPOLATE_UNDEFINED = 0; const INTERPOLATE_AVERAGE = 1; const INTERPOLATE_BICUBIC = 2; const INTERPOLATE_BILINEAR = 3; const INTERPOLATE_FILTER = 4; const INTERPOLATE_INTEGER = 5; const INTERPOLATE_MESH = 6; const INTERPOLATE_NEARESTNEIGHBOR = 7; const INTERPOLATE_SPLINE = 8;
Ну, вы можете скачать PHP Source, добавить функцию фильтра и скомпилировать php.
здесь вы можете найти фильтры https://github.com/php/php-src/blob/master/ext/gd/libgd/gd_interpolation.c#L481
вот случай коммутатора, где вы должны применить метод https://github.com/php/php-src/blob/master/ext/gd/libgd/gd_interpolation.c#L2530
здесь вы можете определить константы https://github.com/php/php-src/blob/master/ext/gd/libgd/gd.h#L137
счастливый взлом: D
Почему вы не используете библиотеку? Я думаю, что если вы будете использовать php-библиотеку, это будет проще. Попробуйте это . Надеюсь, это поможет вам.