Image Version Component

This article is also available in the following languages:
By tom_m
Generate thumbnails from images within your app dynamically with many options to control how the images are resized.
UPDATED May, 21 2010 This code was very dated and I've recently fixed some bugs and added new features. Please be sure to stay current with this project on github. It's been very well tested, but please bring up any bugs that may exist.

Image Version component and helper allow you to very easily make various versions of images in your Cake app. Typically speaking -- thumbnails. It allows you to set the way in which images are cropped or sized to fit, "letterbox" effect, background fill color, quality settings, sharpening, and more.

Requirements: GD Library and PHP modules to work with GD.

Just include the component in your controller and optionally use the helper.
You can grab the code from github: http://github.com/tmaiaroto/image_version

Example Component Usage


// Example controller method...don't forget to include the component.
var $components = array('ImageVersion');

function view() {
   $image = $this->Model->find('first');
   // Remove any existing image, so the thumbnail is generated each time in this case
   $clear = $this->ImageVersion->flushVersion($image['Model']['file'], array(65, 50), true);
   // Create the thumbnail(simplest usage)
   $this->set('thumbnail', $this->ImageVersion->version(array('image' => $image['Model']['file'], 'size' => array(65, 50))));
}

// Example view template
<img src="<?php echo $image?>" />



Example Helper Usage


// In a view template...I have a Model with a file column that has a path to the source image.
// Of course be sure to put in your controller var $helpers = array('ImageVersion'); 
<?php 
$modelName 
Inflector::singularize($this->name); 
foreach (${
strtolower($this->name)} as $entry): 
    echo 
$imageVersion->version(array('image' => $entry[$modelName]['file'], 'size' => array(7575), 90'crop' => true));
endforeach;
?>

The component and helper are both well commented, but basically you're passing in an array with the source image path (anything from the webroot of your application), an array with X and Y dimensions, then optionally, quality, sharpening (not applicable for images with transparency) and other options for cropping/letterbox, etc. In the example above for the controller I also call the flushVersion() method which actually deletes the files I'm creating each time. I would recommend making such a call during development, or on a link to have perhaps a control for a visitor to clear the images (saves you from deleting them manually to see updates).

Comments

  • Posted 10/04/10 12:22:21 PM
    I noticed that when i set equal width and height for thumbnail, it will always be generated as square, even if I set $crop=false and my image is not square.

    The fix is easy:
    find line 164

            // If the thumbnail is square        
            if($thumbSize[0] == $thumbSize[1]) {
    and add the extra condition:

            // If the thumbnail is square and we're cropping
            if($thumbSize[0] == $thumbSize[1] && $crop) {
  • Posted 01/18/10 07:48:07 AM
    Hi, i'm having a problem with createPath function, this message is show "Warning (2): mkdir() [function.mkdir]: Invalid argument [APP\controllers\components\image_version.php, line 270]", how a can resolve this problem, my upload dir is "webroot/files/imagens/portfolios/100x100"
    • Posted 01/18/10 11:55:16 AM
      @Matheus

      What is the argument that you pass to mkdir()? Also, if you downloaded my updated component file, the mkdir() function that's called in createPath() occurs on line 288. In my file, line 270 is a comment line. So if you've changed the code around, I'm not sure I'll be able to help much.
      • Posted 01/18/10 07:30:21 PM
        @Kevin DeCapite

        Hi, I update Image Version Component and worked. Thx for help
  • Posted 11/08/09 07:24:27 PM
    Just an FYI for those who develop on a Windows platform. This component and helper will not work as-is. There are issues with the DS constant as well as Windows root paths ("C:\" instead of "/"). Since I develop on my
    Windows PC and deploy to Linux, it's of enough benefit to me to rework these files to be more cross-platform compatible. I will re-post when finished but wanted to provide a heads-up for anyone stopping by here first.

    UPDATE: I made some changes to the component file (left the helper alone) and posted the new file on my blog here: http://www.decapite.net/web-development/cakephp-image-version-component-update
  • Posted 08/03/09 03:24:06 PM
    I noticed that images with upper-case file extensions wouldn't be processed. Therefore I changed the following line (80) in app/controllers/components/image_version.php:
    switch($originalFile->ext()):
    into this:
    switch(strtolower($originalFile->ext())):
    • Posted 08/03/09 07:03:55 PM
      I noticed that images with upper-case file extensions wouldn't be processed. Therefore I changed the following line (80) in app/controllers/components/image_version.php:
      switch($originalFile->ext()):
      into this:
      switch(strtolower($originalFile->ext())):

      Good call! Thanks! I just ran into that problem.
  • Posted 05/16/09 10:29:06 AM
    I get the error 'headers already sent' when I insert the component in $components. The error points to image_version.php:277 (end of file) and controller.php, line 640 (convience wrapper for header).

    I use Cake 1.2.2.8120....
  • Posted 03/08/09 11:56:44 PM
    Be sure that your memory setting in php.ini is high enough if you're making thumbnails from large images. A 2.6MB JPEG did not resize for me with a default 32M memory limit in php.ini on a server with 256MB RAM. I don't know exactly how much memory it takes or if having a server with more RAM changes things, but setting the memory limit to 64M in php.ini did the trick. Alternatively, you might want to limit the size of images being uploaded to your application for many other reasons as well.
  • Posted 11/07/08 07:02:58 PM
    Just a little comment to point out a problem I had.

    When returning path, you may have trouble if you have your webroot defined somewhere else, i.e. "public_html" (for CPanel in my case) instead of 'webroot':
     
    $finalPath = substr(strstr($outputPath->Folder->path.DS.$outputPath->name().'.'.$outputPath->ext(), 'webroot'), 7); 

    I corrected this using

     
    $finalPath = substr(strstr($outputPath->Folder->path.DS.$outputPath->name().'.'.$outputPath->ext(), WEBROOT_URL), strlen(WEBROOT_URL)); 
    where WEBROOT_URL is a custom defined var constant by me, in all ocurrences.

    Anyway, great job, it works great!

    cheers
  • Posted 11/06/08 10:39:14 PM
    Just a quick note about GD and PHP settings... I recently ran into a problem where there were some jpg images that weren't closed properly and there was some unexpected end of file type warnings when opening...BUT they did open in applications on my computer. They even displayed in the web browser. The problem was that GD saw the error and spit out blank black (the background color) image versions / thumbnails.

    To solve this, I had to change a php.ini setting:
    gd.jpeg_ignore_warning
    Had to be set to 1.

    For shared hosting I know this may be problematic, perhaps try ini_set() in the component somewhere.

    Otherwise, you'll have to take all those "bad" jpg files and re-save them in some image editing program that doesn't make a mess of them.
  • Posted 11/02/08 12:21:53 AM
    Great work for this components, but i found that thumbnail generated from a transparent png loss it transparent background and replace by black color.

    Any fix?
    • Posted 11/06/08 12:47:40 AM
      Great work for this components, but i found that thumbnail generated from a transparent png loss it transparent background and replace by black color.

      Any fix?

      Thanks for pointing that out...I'll figure it out and post a fix when I get a free moment. Should be under the " case 'png': " part somewhere, perhaps PHP had a simple setting. I know you can change the background color...but I don't immediately know if it can be transparent. I'm sure it can. More on this later...

      edit: You can probably add something like the following to right above where the case for png creates the image.
      [code] imagealphablending($new_im, false);
      imagesavealpha($new_im, true);
      [code]

Comments are closed for articles over a year old