Automating creation and caching of image thumbnails

Tags:

The other day I needed to create some thumbnail images. You know, the usual stuff: Admin uploads image, needs it resized to a smaller one for preview or such…

I thought, why bother with writing code manually in the admin to create the thumbnail? I mean, the requirements for its size might change, the path to thumbnails might change… The whole thumbnail might not even be used after some time!

I say this is a view matter. HTML has always provided the means to define image sizes, but as you hopefully know, sending bigger images than you need is a waste of bandwidth and slows things down unnecessarily.

So what about a class which you could easily use in your view layer to display thumbnails?

Essentials

Essentially the class should be easy to use. Throw it an image’s name, similar to what you’d do for an img tag, and it should give you a thumbnail of that image. Of course, you must be able to tell it the size you want it to be too.

It should also automatically store the image somewhere. I’ve seen some solutions to this which use an external PHP file, which is passed as the src for the image… it then dynamically resizes the image… on every request. Not a good idea, as it’s quite slow especially with big images.

So how about something like this?

<img src="<?= thumbnail('images/hello.jpg', 50, 50); ?>" alt="Hello there" />

Wouldn’t that be nice? Yes! And that’s what I wanted!

Great! So how do we do this?

I decided to first create a class for handling basic image operations, such as resizing images and saving them… well, in fact it is the only thing the class does for now, since I didn’t need it to do anything else yet.

Enter CU_Image, an image helper class. The usage is simple:

$image = new CU_Image('hello.jpg');
$image->resize(50, 50)
      ->save('thumb.jpg');

so that would already be quite simple for doing thumbnails. Bear in mind that the CU_Image class is very basic, but it demonstrates the idea.

I still want to streamline it. The CU_Image class itself isn’t able to do nice tricks like caching the newly created thumbnail and such.

Here’s another class: CU_Image_Thumbnailer, which uses CU_Image to create thumbnails and save them on the disk automagically.

Using the thumbnailer is perhaps even simpler:

//Optionally set the path, defaults to images/small
CU_Image_Thumbnailer::setOptions(array(
    'path' => 'images/thumbnails'
));
 
$thumb = CU_Image_Thumbnailer::getInstance()->getThumbnail('hello.jpg', 50, 50);

The getThumbnail method is where the magic is at. It takes the image file, resizes it, saves it to the specified thumbnail path and finally returns you a quite-certainly-unique filename to the newly created thumbnail. And what’s even better, we could call this method times and times again for the same image, and it will only generate the thumbnail on the first time!

Final steps

Now that we have the convenient image classes at hand, it’s a very simple job to do the thumbnail function I mentioned earlier:

function thumbnail($file, $w, $h)
{
    return CU_Image_Thumbnailer::getInstance()->getThumbnail($file, $w, $h);
}

We could also implement this as a Zend Framework view helper:

class CU_View_Helper_Thumbnail
{
    public function thumbnail($file, $w, $h)
    {
        return CU_Image_Thumbnailer::getInstance()->getThumbnail($file, $w, $h);
    }
}

These two could be safely used in the view layer. The first time the thumbnail is being created the user may have to wait a bit longer, but after that the thumbnailer class will simply return the filename without generating anything so it’ll be a breeze.