Выберите алгоритм изменения размера изображения в PHP

Функция 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); или такие вещи, кажется, не работают.


Согласно тестам, которые я сделал (на другом языке), «билинейное изменение размера» иногда дает лучший результат, чем бикубическое, а иногда наоборот (зависит от того, уменьшается ли оно или уменьшается).

8

Решение

Альтернативой является 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 приводят к одному и тому же изображению.

9

Другие решения

imagecopyresampled основана / часть LibGD, посмотрев на исходный код LibGD, вы можете ясно увидеть его реализация , также документация не является неоднозначной об используемом алгоритме, поскольку заявлено, что:

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

Так как же выбрать алгоритм изменения размера, используемый 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;
5

Ну, вы можете скачать исходный код PHP, добавить функцию фильтра и скомпилировать 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

0

Почему вы не используете библиотеку? Я думаю, что если вы используете библиотеку php, это будет проще. Пытаться этот. Надеюсь, это поможет вам.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector