Creating Image Thumbnails using PHP and ImageMagick

Last month I wrote a post on using Photoshop and Javascript to generate thumbnails. That's useful if you have to process a bunch of images for a website you're making, but what if you want to have a function on your website that accepts image uploads and then dynamically generates thumbnails? There's a lot that goes into that, but today I'm going to provide a basic PHP function (using ImageMagick) that gets the image processing part of the job done. I'll give the code, then go through it:

define('THUMB_WIDTH', 60);
define('THUMB_HEIGHT', 80);
define('MAGICK_PATH','/usr/local/bin/');

function makeThumbnail($in, $out) {
    $width = THUMB_WIDTH;
    $height = THUMB_HEIGHT;
    list($w,$h) = getimagesize($in);

    $thumbRatio = $width/$height;
    $inRatio = $w/$h;
    $isLandscape = $inRatio > $thumbRatio;

    $size = ($isLandscape ? '1000x'.$height : $width.'x1000');
    $xoff = ($isLandscape ? floor((($inRatio*$height)-$width)/2) : 0);
    $command = MAGICK_PATH."convert $in -resize $size -crop {$width}x{$height}+{$xoff}+0 ".
        "-colorspace RGB -strip -quality 90 $out";

    exec($command);
}

Those first 3 define's are the configuration for this function. The first two define the width and height, in pixels, of the thumbnails that will be generated. The other define specifies the path to ImageMagick's convert program.

Now, on to the function itself. I've called it "makeThumbnail" (appropriately), and it takes two parameters. $in is the path to the image file that's going to be processed, and $out is the path we want to save our thumbnail to. Simple enough. Next, the first 3 lines of the function:

    $width = THUMB_WIDTH;
    $height = THUMB_HEIGHT;
    list($w,$h) = getimagesize($in);

Those first two lines are just saving our configuration parameters into variables named $width and $height. The third line stores the width and height of the input image in the variables $w and $h, respectively. Next, our first little bit of math:

    $thumbRatio = $width/$height;
    $inRatio = $w/$h;
    $isLandscape = $inRatio > $thumbRatio;

$thumbRatio is the aspect ratio that our thumbnail will have. $inRatio is the aspect ratio of the input image. We then compare these to figure out whether the input image is landscape or portrait oriented, with respect to the thumbnail we're going to generate. We want to figure this out because we're going to (most likely) do some cropping when generating our thumbnail, and how we crop the picture will depend on its orientation. And now here's where the magic(k) happens:

    $size = ($isLandscape ? '1000x'.$height : $width.'x1000');
    $xoff = ($isLandscape ? floor((($inRatio*$height)-$width)/2) : 0);
    $command = MAGICK_PATH."convert $in -resize $size -crop {$width}x{$height}+{$xoff}+0 ".
        "-colorspace RGB -strip -quality 90 $out";

The $size and $xoff variables hold the values that will be passed to convert to appropriately resize and crop the image. The logic is written such that portrait images will have their bottom cropped off to fit the proportions of the thumbnail. Landscape images will have equal amounts of left and right side cropped off. "-colorspace RGB" converts the image to the RGB colorspace, which is useful if you're using this function to process uploaded images from a web form... sometimes you'll get images that are using CMYK, and if you don't convert to RGB colorspace, you get larger, sometimes undisplayable, images. "-strip" strips out the color profile information, which most browsers don't pay attention to anyway (again, this function is web-oriented), so stripping it out just helps reduce your file size. "-quality 90" specifies the compression (quality) value for output. I find that using a value of 90 gives good-looking images that are still pretty small in file size. And to finish out:

    exec($command);

The last line executes the command we've constructed. Any questions? Use the comment form below.

Comments

ah, man --- been searching and searching for some ImageMagick 'code' that made sense and yours is short, simple and sweet.

Merci!

Hi, do you know what can I do to make a multiple pdf thumbnail with imagemagick and php for just the first page?

Thanks

MrK, if you're trying to generate PDFs with PHP, you probably want to use something like PDFLib, not ImageMagick.

Thank you Chadwick , but what I'm looking for is for a script using imagemagick and ghostscript to make a thumbnail for just the first page of a PDF document, what I get when I run the script above are multiple thumbnails. Do you know if it's possible.

Thank you

Ah, well, I don't have experience with ghostscript, so I can't help you there.

Nice script very simple and useful. but I got problems in our webserver I got "Warning: exec() has been disabled for security reasons" got any ideas on how to fix this? Is there any alternative for the exec() command in your code? Im currently looking for a solution. Thanks in advance.

Sonny, it sounds like your webserver is running PHP in safe mode most likely, which disables the ability to run commands. The only ways around it that I can think of is to ask your host to disable safe mode, or use the Imagick module for PHP if your host has it installed. Barring that, use a different host if you can? I use Dreamhost whenever possible! Sorry I can't offer more help.

I have Imagemagick installed in my server. I am using Imgaemagick to convert PDF files into JPG imgaes. I use exec("convert test.pdf test.jpg") command. This converts my pdf into jpg perfectly in my local system. But unable to convert in the server. Other commands for image manipulations are working fine.

To extract the first page of a multi-page PDF with ImageMagick simple add [0] to the end of the source file.

Thanks kory. Learn something new every day!

Hi Chadwick How do I call the function, and how can I see the my newly created thumbnail? Thank you

Frank, you would call the function in the context of some other script... that's more of a general PHP question.

As for how you can see the thumbnail once you call the function, the $out variable you pass to the function is the path to the image file that gets output by the function, so whatever you specify there is where you'll find your newly created thumbnail.

hi i would like to know if it is possible to make only one thumbnail out of pdf with multiple pages?!? if so, how can we do that?

dhongki, according to kory's comment (above):

"To extract the first page of a multi-page PDF with ImageMagick simple add [0] to the end of the source file."

I am using wamp in windows.It is located in c: drive.So what should be d $in and $out

good , but ,,,,,,,, i don't wanna use commands , in fact you had to explane the OO interface of imagMagick instead of executing commands with the exec() function , thanks at all !