Select PHP's Image resizing algorithm
Asked Answered
U

4

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)

Unknit answered 18/1, 2017 at 14:37 Comment(5)
As noted here by someone: "It should be noted that the imagecopyresampled() function is much more blurry than Photoshop CS's default bicubic funtion. And looks similar to a blury version of Photoshop's bilinear function. The documentation fails to note which algorithm is used in resampling."Unknit
It looks like it doesn't apply to imagecopyresampled - I shall delete it as incorrect while I try to work it out. Sorry.Adopted
As stated in this question, setting imagesetinterpolation($dst, IMG_BILINEAR_FIXED); or such things doesn't seem to work.Unknit
"How can I modify the resizing algorithm used by PHP?" wouldn't it be easier to just write your own custom PHP function rather than modify the programming language itself (if that's even allowed)?Marimaria
I've edited a keyword in your Question, since I understand it better now. Don't say "I want to modify algorithm X" when really you mean "I want to select option of algorithm X"... The former suggests you want to modify PHP source code's functions. You just want to enable some resize option... correct?Marimaria
T
13

An alternative is the imagescale() function, that allows specifying the interpolation algorithm as a parameter:

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

According to the documentation $algorithm can be:

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

A test in PHP 7.0.15 (comparing file hash) shows that BICUBIC and BICUBIC_FIXED result in a different image, while BILINEAR_FIXED and NEAREST_NEIGHBOUR result in the same image.

Tenstrike answered 30/1, 2017 at 14:2 Comment(5)
Seems great! I'll test asap.Unknit
@Unknit this is the Answer I was going to give myself. I think it's correct for your needs...?Marimaria
For me using imagescale() with IMG_BICUBIC makes the image even blurrier, and introduces weird artifact in flat colours.Uranium
I can't say which filter produces the best results but avoid using IMG_BICUBIC_FIXED, IMG_BILINEAR_FIXED and IMG_NEAREST_NEIGHBOUR as those methods produce really bad images (I tested downscaling).Waugh
An important note is the "or anything else" in the manual. I noticed that I can use many more filter types, listed here php.net/manual/de/function.imagesetinterpolation.php . Probably all except IMG_WEIGHTED4 (see php manual for imagescale). I had good results with e.g. IMG_CATMULLROM for downscaling (tested in PHP 7).Elective
S
5

imagecopyresampled is based/part of LibGD , by looking at the source code of LibGD, you can see clearly its implementation , also the documentation is not ambiguous about the used algorithm as it's stated that :

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.

So how can you select the resizing algorithm used by PHP?

If you insist/must use LibGD functions, you can't (unless you recompile PHP with a LibGD fork you code just for this matter).

However if you're free to use another image manipulation library, you can simply use one that use a different algorithm for resizing, for example Imagick seems to offer a wide range of interpolations but since the documentation is quite mute about it here is the constants needed to use the Imagick::setImageInterpolateMethod(int $) method :

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;
Shandrashandrydan answered 29/1, 2017 at 19:43 Comment(0)
S
0

Well you could download the PHP Source , add your filter function and compile php.

here you can find the filters https://github.com/php/php-src/blob/master/ext/gd/libgd/gd_interpolation.c#L481

here is the switch case where you have to apply the method https://github.com/php/php-src/blob/master/ext/gd/libgd/gd_interpolation.c#L2530

here you can define constants https://github.com/php/php-src/blob/master/ext/gd/libgd/gd.h#L137

happy hacking :D

Shearin answered 27/1, 2017 at 8:12 Comment(1)
There is nothing wrong with this Answer. It's correct for the previous wording of Question which suggested the Asker wanted to modify the source code of a re-sampling algorithm. I've edited the Question. @VitalijMik, check the new edit if you wish to change your Answer also...Marimaria
B
-1

Why do you not use a library? I think that if you use a php library it will be more easy. Try this one. Hope it will help you.

Bistort answered 27/1, 2017 at 7:46 Comment(2)
@Cakpep check the new edit & re-read for true meaning of Question. You can edit your Answer with new info, if you wish...Marimaria
This library won't allow to change algorithm. See this comment: http://php.net/manual/en/function.imagecopyresampled.php this is the function used internally by library. I could not find information on which algorithm is used by the function.Unknit

© 2022 - 2025 — McMap. All rights reserved.