Select PHP的图像调整算法

Select PHP's Image resizing algorithm

函数 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);

如何select PHP使用的调整大小算法?
注意:如in this question所述,设置imagesetinterpolation($dst, IMG_BILINEAR_FIXED);或类似的东西似乎不起作用。


根据我所做的测试(用另一种语言),“双线性调整大小”有时会比双三次得到更好的结果,有时则相反(取决于它是缩小还是放大)。


(来源:dpchallenge.com

你为什么不用图书馆?我认为如果你使用 php 库会更容易。尝试 this one。希望对你有帮助。

那么您可以下载 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

imagecopyresampled 是 LibGD 的 based/part ,通过查看 LibGD 的源代码,您可以清楚地看到它的 implementation ,并且文档对使用的算法没有歧义,因为据说:

If the source and destination area differ in size, the area will be resized using bilinear interpolation for truecolor images, and nearest-neighbor interpolation for palette images.

那么你如何select PHP 使用的调整大小算法?

如果您 insist/must 使用 LibGD 函数,则不能(除非您使用 LibGD 分支重新编译 PHP,您的代码就是为了这个问题) .

但是,如果您可以自由使用其他图像处理库,您可以简单地使用一个使用不同算法调整大小的库,例如 Imagick 似乎提供了广泛的插值,但由于 documentation对此非常沉默这里是使用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;

另一种方法是 imagescale() 函数,它允许将插值算法指定为参数:

imagescale($image, $new_width, $new_height, $algorithm);

根据文档 $algorithm 可以是:

One of IMG_NEAREST_NEIGHBOUR, IMG_BILINEAR_FIXED, IMG_BICUBIC, IMG_BICUBIC_FIXED or anything else (will use two pass).

PHP 7.0.15 中的一项测试(比较文件哈希)显示 BICUBIC 和 BICUBIC_FIXED 产生不同的图像,而 BILINEAR_FIXED 和 NEAREST_NEIGHBOUR 产生相同的图像。