dark

Generate thumbnails with Perl and Image Magick

blank

Putting photos on a website has always been a pain. There were always a few steps you had to do, before they could be seen on your webpage. Of course, nowadays there are services like Flickr, Picassa, Panoramio, Facebook … but you still have to go through quite some steps before you pictures are online.

One thing you don’t have to do with those online services like Flickr etc. is generating smaller sizes of your photos, also called thumbnails. But if you maintain your own website, you will have to downsize them on your own.
Being a programmer, I’m the happiest when I’m the laziest. So, in case of websites and photos, I don’t want to create the zillion of thumbnails that I need on my page.
Zillion? Isn’t that a little bit exajurated? Well, mostly you will need more than one thumbnail for every picture you will upload:
– one thumbnail is needed for on the thumbnail page
– one smaller thumbnail is needed for a small thumbnail preview bar
– one even smaller thumbnail is needed for marking the photo on a Google Map
– one smaller sized photo is needed for previewing it on the website
– and finally the original image is also put available for download on the site

We’ll need at least 4 extra images for every photo. Okay, I could generate all those thumbs at home and then upload them all together, but that is wasting bandwidth and time and we know how precious they both are.

Being a programmer in my professional life, I have the deviation to automate everything I know or do, with a Perl script. And this situation is again perfect for such a script.

First of all, the following code will make heavy use of the Image::Magick Perl module, which can be downloaded from either CPAN or your distro’s repositry.

The several steps of manipulating the original image, were actually inspired by the following two links:
http://www.imagemagick.org/Usage/thumbnails/#glass_bubble
http://stackoverflow.com/questions/3973392/facebook-like-resizing-of-images-using-imagemagick

The second link explains how to resize and crop, the first link explains how create neat thumbnails using rounded corners, lighting effects and more. Now, both links give examples using the command line Image Magick tools. I’ve seen a lot of code which will call these command line tools instead of using the Image::Magick module. That is of course, NOT the way.

On with creating our thumbnails! First, the image needs to be resized:

my $img = 'image.png';
my $magick = new Image::Magick;
$magick->Read($img);
my ($width, $height) = $magick->Get('width', 'height');

$magick->Resize(geometry => int($width/2).'x'.int($height/2));
$magick->Resize(geometry => '180x');
$magick->Resize(geometry => 'x180<');
   
my($nwidth, $nheight) = $magick->Get('width', 'height');
my $xpos = int(( $nwidth - 120 ) / 2) - 60;
my $ypos = int(( $nheight - 120 ) / 2) - 60;
$magick->Crop(geometry => "120x120+$xpos+$ypos", gravity => 'Center');

The above code will generate a thumbnail which are 120px by 120px big (or small), using a cropped field out of the 180px by 180px scaled image. The position of the cropped field is somewhat in the middle of the image, where usually the object of the photo can be found.

Next we’ll add some effects to our downsized image. We’ll do this by cloning the resized Image Magick object, that was created in the code above:

my $thumb_mask = $magick->Clone();

Once the object has been cloned, we can start by adding effects to the new object:

$thumb_mask->Set('alpha' => 'Off');
$thumb_mask->Colorize( fill => 'white', opacity => '100%' );

$thumb_mask->Draw( fill => 'black',
                   primitive => 'polygon',
                   points => '0,0 0,15 15,0');
$thumb_mask->Draw( fill => 'white',
                       primitive => 'circle',
                       points => '15,15 15,0');
my $new_2 = $thumb_mask->Clone();
$new_2->Flip();
$thumb_mask->Composite( compose => 'Multiply', 'image' => $new_2 );

my $new_3 = $thumb_mask->Clone();
$new_3->Flop();
$thumb_mask->Composite( compose => 'Multiply', 'image' => $new_3 );

$thumb_mask->Set('background' => 'Gray50');
$thumb_mask->Set('alpha' => 'Shape');

$thumb_mask->Raise(raise => 'True', geometry => '4x4');

By now we should have a rounded gray icon, based on the size of the thumbnail we’ve created above.

Next we will create some lighting and shading effects so that the thumbnail will look more like a button.

my $thumb_lighting = $thumb_mask->Clone();
$thumb_lighting->Set('bordercolor' => 'None');
$thumb_lighting->Set('border'      => '1x1');
$thumb_lighting->Set('alpha'       => 'Extract');
$thumb_lighting->Blur('geometry'       => '0x10');
$thumb_lighting->Shade(geometry => '80x40');
$thumb_lighting->Set('alpha'       => 'On');
$thumb_lighting->Set('background'  => 'Gray50');
$thumb_lighting->Set('alpha'       => 'Background');
$thumb_lighting->AutoLevel(channel => 'alpha');
$thumb_lighting->[-1]->Function(function => 'polynomial', parameters => [3.5, -5.05, 2.05, 0.3]);

my $new_4 = $thumb_lighting->Clone();
$new_4->Set(alpha => 'Extract');
$new_4->Blur(geometry => '0x2');

$thumb_lighting->Composite(compose => 'Multiply', image => $new_4);
$thumb_lighting->Chop(geometry => '1x1');

Finally, all that rests is putting all the images togehter and saving the file to disk:

$magick->Set('alpha' => 'On');
$magick->Composite(compose => 'HardLight', image => $thumb_lighting);
$magick->Set('alpha' => 'Copy');
$magick->Composite(compose => 'CopyOpacity', image => $thumb_mask);
$magick->Write('thumbnail.png');

Important to know is, since creating rounded corner will add some transparency to the original image, the newly created thumbnail must be save as either a GIF or PNG image, while those are the only two image formats which support transparency in images.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Previous Post

Recovering Subject column in Apple’s Mail.app

Next Post

Geotag your photos with Perl and GPX files

Related Posts