Zend Framework Dynamic Image Resize Integration

I decided to write a tutorial on how to achieve dynamic image resizing with the Zend Framework. This Tutorial includes various aspects and key concepts of the Zend Framework such as Caching and Routing and should give you a good insight in how to adjust these components to suit your needs.

Why do i need this?

At first, let me explain what i mean by “Dynamic Image Resizing” – in most Content Management Systems, it is a valuable asset to not have to upload any images in their final constraints, but rather to upload them as a hi-res image file in the backend and let the CMS do the magic of scaling and cropping the image automatically so that they are nicely adjusted to fit the boundaries that are being set by the frontend HTML-Template. Especially when it comes to thumbnail galleries, where you have countless images in various sizes. Imagine the effort if you had to create each thumbnail manually in Photoshop and then a design change would force you to do it all over again. For this we have a webserver with PHP and the GD Library that will do the work – we just deliver it the right proportions.

Further considerations

As dynamically resizing images on the fly with PHP and the GD Library takes precious ressources, we should think about caching the images, once they have been generated. This can be also done with the Zend Framework, which provides a comprehensive Caching API allowing us to store generated images safely on the Server and access them from there once requested.

A request for dynamically generated images will take some GET variables, in order that we can submit the different parameters that are necessary to create the desired image. How big is it gonna be? How should it be cropped? Do i need to preserve possible transparency with PNGs? This would potentially lead to complicated urls such as:

A bit ugly and not looking like an image file at all. Wouldn’t it be nice to have something more like this?

With the Routing possibilites of Zend Framework, we’re gonna take care of that. While most of the time it doesn’t really matter how the image URLs are going to look like, it’s actually cool to have this feat because the links don’t look like server generated images at all, which gives you extra bragging rights. Also it’s possibly gonna help with potential MIME-Type issues in some cases, because the URL spitting out the image already has the correct extension for its corresponding MIME-Type.

The Image Processing Library of choice

Of course we could do the image processing all by ourselves with countless lines of PHP code, but that would be too easy, wouldn’t it? Instead, i recommend using a library, that encapsulates many practical image processing functions. The library i’ve been using for years now is verot’s upload.class.php – it is released under the GPL license and includes many image manipulating functions out of the box such as cropping, resizing, converting file types, which we need for our little tutorial here.

Wrapping it up

For all the necessary Image Processing functions, we’ll write a small class that wraps them togehter for ease of use later in the application.

This will take care of our three basic resize options:

  • Resize, then crop the image to exact dimensions.
  • Resize, then preserve original aspect ratio – if either width or height is set to zero it will adjust automatically, if both are set, image will fit inside the given dimensions.
  • Resize, then fill the image with a (transparent) background to match the given dimensions.

If you were looking for a simple way to do some image resizing and cropping in PHP and generate some thumbnails with it, then that’s it, go ahead, snatch the script and code away, have fun! If you’re looking to integrate the whole enchilada with Zend Framework, i suggest you read a bit further.

Implementing with the MVC Architecture

After getting the technical basics ready, we wanna take care of the image processing component into Zend Framework’s architecture. So we’ll set up a Controller inside our default module, which shall take care of processing images exclusively. The Controller will take care of receiving the parameters for height, width and resizing type as well as integrate a caching mechanism and deliver the right headers to the browser so that the images are being displayed correctly.

The Controller is actually pretty simple, with just an indexAction and not depending on any view scripts or models.

This is the complete class. There’s a few thing’s going on in there, which i’ll explain in detail in the following paragraphs.

Request and Response

First, our controller will fetch some get parameters from the URL which tell our Image Processor Class the dimensions and the resize style, as well as the image format.

As a next step, we’re gonna handle the Response that our server will send to the browser. Since we want to output our image directly to the browser, we first have to turn off any other output of Zend Frameworks MVC – the following care will disable the standard website layout as well as the rendering of a specific action’s view.

Now we need to set the correct headers so that the browser recognizes the data sent as an image. During this process, we also want to take care of the browser cache control. In case the Image hasn’t changed on the server since the visitor’s last request, we’ll send a HTTP 304 Code, which will tell the visitor’s browser to fetch the image from it’s internal cache if applicable.

Next, we’ll call the actual image rendering function and set the rest of the headers that will take care of future requests caching. In the last few lines we’ll take care of Zend Framework’s internal Caching functions. This is acually very straightforward. We’ll set a cache id consisting of the image’s parameters and the actual image’s path and filename. This makes sure we can identify each image’s cache entry uniquely. At last, we just store the raw data of the image inside the basic Zend Framework cache by triggering it’s save() function.

That’s it! Dynamic Image Resizing achieved, caching functionality inclusive. In the original Controller class further upwards, there’s a few more functions – one action will give us the original file back (hiresAction), the other two are helper methods that give us some information about the original images, like their filesize and mimetype.

I hope having helped with sharing these bits of code with the world. It is my first tutorial of this kind, so feedback is very welcome. I hope the steps are clear for everyone, if not, ask away, i’ll be glad to help! Until next time!

9 Comments

  1. Hello, thank you for the tutorial. Actually I’m getting a error:

    Fatal error: Class ‘RF_Image_Resizer’ not found in PATH\application\controllers\ImageController.php on line 13

    I changed the line 13 from RF_Image_Resizer to My_Image_Resizer and isn’t working.
    The My_Image_Resizer.php file is into model folder.

    I hope you can help me.

    Thank you.

    Reply
    • Ok, I got fixed adding Application_Model_ before call the class, now I’m getting this error:

      An error occurred
      Application error
      Exception information:
      Message: No entry is registered for key ‘imageCache’

      How should be the entry in application.ini?
      Thank you for your time.

      Reply
    • Hey Juan
      Thanks for the Feedback, of course it should be My_Image_Resizer, i fixed that in the example. You shouldn’t put the File in your Model folder though, it’s supposed to be automatically loaded via Autoloading from your library folder. You can read more on the subject here: http://framework.zend.com/manual/1.12/en/zend.loader.autoloader.html

      On your second issue concerning the cache error: I forgot to include the Cache initialization which i usually do in the Bootstrap file and then put it in the Zend_Registry to make it globally available, although it wouldn’t be necessary for this simple Image Rendering example. I updated the Code Snippet on the blog in order that the Cache gets initialized directly inside the class, just make sure the Directory DOCUMENT_ROOT/cache/images/ exists and is writable (chmod 777). Hope that fixes your problem!

      Reply
  2. Hey Diego,

    Nice concepts here. I’ve adapted it, but I think there’s a problem in the logic – you seem to be processing the image even if the image is in the cache, which defies the point of the cache. Am I missing something there?

    Thanks for the time you put into this otherwise!

    Reply
    • Hi Dan

      Thank you for the input, and you are right, this is something i also noticed a while ago when i did some refactoring of my codebase.
      Strangely though, the caching process of ZF seems to take care of that fact and not re-process the image if it is found in the cache – though it doesn’t make sense from a logical point of view as you pointed out. Nonetheless, i adjusted the code to make sense now – it should be working either way though!

      Reply
  3. You have not covered in your article how to get from using parameters to using the zend routing. As you promised in your article.

    “A request for dynamically generated images will take some GET variables, in order that we can submit the different parameters that are necessary to create the desired image. How big is it gonna be? How should it be cropped? Do i need to preserve possible transparency with PNGs? This would potentially lead to complicated urls such as:

    http://www.myawesomewebsite.com/generate_image.php?id=4756638&width=384&height=654&crop=true&format=jpg
    A bit ugly and not looking like an image file at all. Wouldn’t it be nice to have something more like this?

    http://www.myawesomewebsite.com/image/4756638/384x654_crop.jpg

    Otherwise good job on the article. I’m a tech blogger as well and I do it for free, so I have to give you thumbs up despite the missing content I had hopped to find.

    Reply

Leave a Comment.