9

The function imagecopyresampled is useful to generate a thumbnail or resize images, while keeping aspect ratio:

$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);

How can I select the resizing algorithm used by PHP?
Note: as stated in this question, setting imagesetinterpolation($dst, IMG_BILINEAR_FIXED); or such things doesn't seem to work.


According to tests I did (in another language), "bilinear resizing" sometimes gives better result than bicubic, and sometimes it's the contrary (depends if it's downsizing or upsizing).


(source: dpchallenge.com)

4

4 回答 4

12

另一种方法是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 产生相同的图像。

于 2017-01-30T14:02:31.567 回答
5

imagecopyresampled是基于/部分 LibGD ,通过查看 LibGD 的源代码,您可以清楚地看到它的实现,而且文档对所使用的算法也没有歧义,因为它声明:

如果源区域和目标区域的大小不同,则将使用双线性插值对真彩色图像调整区域大小,对调色板图像使用最近邻插值

那么如何选择 PHP 使用的大小调整算法呢?

如果您坚持/必须使用 LibGD 函数,则不能(除非您使用 LibGD fork 重新编译 PHP,否则您只是为此编写代码)。

但是,如果您可以自由使用另一个图像处理库,您可以简单地使用一个使用不同算法来调整大小的库,例如 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;
于 2017-01-29T19:43:31.893 回答
0

你为什么不使用图书馆?我认为如果您使用 php 库,它会更容易。试试这个。希望它会帮助你。

于 2017-01-27T07:46:50.910 回答
0

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

于 2017-01-27T08:12:15.323 回答