For some time I’ve been using GD lib for generating thumbnails. The solution was never satisfying since you need different functions to output different image formats. For some reason the getimagesize() function stoped working so I decided it was time to rewrite the code, and this time Imagick caught my attention.
Thanks to the Imagick PHP class the thumbnail generating process is really easy. You don’t have to do much, just pass the dimension of the thumbnail, what filter to use, blur factor and if it should try to use best-fit. Done! Except for one thing. There are 16 filters to choose from and the computation penalty varies. So which filter is the best one?
For the tests I was using a JPEG photo with dimensions 2551 x 1701 (w x h) and 949 Kib in size. To test the filter I created thumbnails in the sizes 640, 200, 180, 130, 75 and 50 pixels in a square box model, that is the thumbnail must not be larger than a 50×50 pixel box. To measure the time it takes for each filter to generate the thumbnails I was using the Linux shell time command:
$ time php resize.php image_Z.jpg
And here is the complete PHP script:
<?php
$filter = Imagick::FILTER_BOX;
$i = new Imagick($argv[1]);
$i->setImageOpacity(1.0);
$h = $i->getImageHeight();
$w = $i->getImageWidth();
echo "According to Imagick the image is ".$w."x".$h." pixels.\n";
$sizes = array(
'_F' => 640,
'_E' => 200,
'_D' => 180,
'_C' => 130,
'_B' => 75,
'_A' => 50
);
foreach ($sizes as $label => $size) {
echo "Resizing to ".$size."x".$size."... ";
$i->resizeImage($size, $size, $filter, 1, true);
$i->writeImage(str_replace('_Z', $label, $argv[1]));
echo “Done\n”;
}
?>
Now I just ran the script for all the filters to measure the times. The times are the mean value of all runs. The size column is simply the size of the 640 pixel thumbnail.
| Filter | Real | User | Sys | Size |
|---|---|---|---|---|
| undefined | 1.273 | 0.645 | 0.110 | 179844 |
| point | 0.967 | 0.795 | 0.155 | 202263 |
| box | 1.006 | 0.840 | 0.140 | 186783 |
| triangle | 1.155 | 0.935 | 0.155 | 178033 |
| hermite | 1.075 | 0.925 | 0.130 | 181151 |
| hanning | 1.216 | 1.045 | 0.150 | 190509 |
| hamming | 1.259 | 0.990 | 0.165 | 191234 |
| blackman | 1.188 | 1.035 | 0.135 | 189332 |
| gaussian | 0.785 | 0.540 | 0.130 | 172981 |
| quadratic | 0.657 | 0.515 | 0.125 | 172130 |
| cubic | 0.769 | 0.605 | 0.150 | 167606 |
| catrom | 0.769 | 0.595 | 0.155 | 186291 |
| mitchell | 0.803 | 0.620 | 0.130 | 179844 |
| lanczos | 0.995 | 0.855 | 0.125 | 190593 |
| bessel | 1.058 | 0.890 | 0.125 | 177809 |
| sinc | 1.178 | 1.000 | 0.135 | 189332 |
Now, let’s picture that with a graph.
Take a look at the smaller thumbnail, less than 200 pixels. It’s here you’ll see the difference between the various filters. For my test image the Quadratic and Cubic filters generates a very blury thumbnail. I guess you have to test the filters for the type of images you will resize, in my case the Lanczos and Catrom filters generated about the same result. I decided to go with Catrom since it is faster.
