Imagick resize filter comparison using PHP

January 24th, 2011

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.

Imagick filter comparison graph

Imagick filter comparison graph (click for larger image)

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.

ffmpeg and h.264 in Debian Lenny

June 10th, 2010

Ever tried to transcode into H.264 using ffmpeg in Debian Lenny just to end up with this message

Unknown encoder ‘libx264′

Here is how you solve the problem:

  1. Download the debian-multimedia-keyring package
  2. Install it dpkg -i debian-multimedia-keyring_2008.10.16_all.deb
  3. Add the Debian Multimedia repository to your sources.list
  4. Run apt-get update and apt-get upgrade
  5. Install the libx264 and ffmpeg packages; apt-get install libx264 ffmpeg or apt-get --reinstall install libx264 ffmpeg

Good luck!

JavaScript Date Format in Swedish

March 10th, 2010

Found myself “late-night-surfing” again, but this time I actually found something interesting. Steven Levithan has written an easy-to-use and easy-to-extend JavaScript date format function. So, to encourage his great work I publish the Swedish translation.

// Internationalization strings
dateFormat.i18n = {
dayNames: [
"Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör",
"Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"
],
monthNames: [
"Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec",
"Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
]
};

The complete code at its latest version can be found at Stevens blog, JavaScript Date Format.