This is a helper + controller combo for CakePHP which I often use. It helps to re-size images at run-time and also aid display them. Oh yes! once the image is resized it also caches them.
First let’s look at helper method.
- class MyHelper extends AppHelper
- {
- function getImageUrl($path, $size, $file)
- {
- $filepath = WWW_ROOT . $path . DS . $size . DS . $file;
- if (is_file($filepath))
- {
- return r(array(WWW_ROOT, DS), '/', $filepath);
- }
- return array
- (
- 'controller' => 'images'
- , 'action' => 'resize'
- , 'file' => $file
- , 'path' => $path
- , 'size' => $size
- );
- }
- }
What above code does? If re-sized version of image already available then return it otherwise ‘/images/resize’ page will handle re-sizing.
So, how to use this? Set ‘My’ in $helpers array of your application controller or the needed controller and use it in view like
- echo $html->image($my->getImageUrl('files' . DS . 'avatars', '75-s', 'test.png'));
Now, you will wonder what ’75-s’ is. This is my way of handling various re-sizing methods, ’75-s’ means resize+crop to 75×75 (square) size. Also it has been assumed that ‘test.png’ exists in ‘[WWW_ROOT]/files/avatars’ directory.
Now let’s move to re-size part. The basic controller/action code contains
- class ImagesController extends AppController
- {
- function resize()
- {
- $file = $this->params['size']
- $path = $this->params['path']
- $size = $this->params['size'];
- $aspect = false;
- $resizedHeight = $resizedWidth = 0;
- // $size = 100; (Proportional - 100 as height or width whichever is longer)
- if (ereg('^([1-9]+[0-9]*)$', $size))
- {
- $aspect = 'p';
- $resizedHeight = $resizedWidth = $size;
- }
- /**
- * $size = 100:h; (Proportional - 100 as height)
- * $size = 100:s; (Square/crop - 100 as height and width)
- * $size = 100:w; (Proportional - 100 as width)
- */
- else if (ereg('^([1-9]+[0-9]*:[h|s|w]+)$', $size))
- {
- list($dimension, $aspect) = explode(':', $size);
- if ('w' == $aspect)
- {
- $resizedHeight = $dimension;
- }
- else if ('h' == $aspect)
- {
- $resizedWidth = $dimension;
- }
- }
- // $size = 100x150; (Exact [not proportional and no cropping] - 100 as width and 150 as height)
- else if (ereg('^([1-9]+[0-9]*x[1-9]+[0-9]*)$', $size))
- {
- list($resizedWidth, $resizedHeight) = explode('x', $size);
- }
- $original = WWW_ROOT . $path . DS . $file;
- $resized = WWW_ROOT . $path . DS . $size . DS . $file;
- list($originalWidth, $originalHeight, $originalType) = getimagesize($original);
- $clipX = $clipY = 0;
- if (false !== $aspect)
- {
- if ('h' == $aspect)
- {
- $ratio = ($originalHeight / $resizedHeight);
- }
- else if ('p' == $aspect)
- {
- $ratio = (max($originalWidth, $originalHeight) / $resizedWidth);
- }
- else if ('s' == $aspect)
- {
- $ratio = (min($originalWidth, $originalHeight) / $resizedWidth);
- }
- else if ('w' == $aspect)
- {
- $ratio = ($originalWidth / $resizedWidth);
- }
- $ratio = max($ratio, 1);
- if ('s' == $aspect)
- {
- $resizedHeight = $resizedWidth = (int)(min($originalWidth, $originalHeight) / $ratio);
- if ($originalHeight > $originalWidth)
- {
- $clipY = (int)(($originalHeight - $originalWidth) / 2);
- $originalHeight = $originalWidth;
- }
- else if ($originalWidth > $originalHeight)
- {
- $clipX = (int)(($originalWidth - $originalHeight) / 2);
- $originalWidth = $originalHeight;
- }
- }
- else
- {
- $resizedWidth = (int)($originalWidth / $ratio);
- $resizedHeight = (int)($originalHeight / $ratio);
- }
- }
- else
- {
- if ($resizedWidth > $originalWidth)
- {
- $resizedWidth = $originalWidth;
- }
- if ($resizedHeight > $originalHeight)
- {
- $resizedHeight = $originalHeight;
- }
- }
- // If both width and height are same as original width and original height
- if ($resizedWidth == $originalWidth && $resizedHeight == $originalHeight)
- {
- copy($original, $resized);
- }
- else
- {
- $types = array(1 => 'gif', 'jpeg', 'png');
- $image = call_user_func('imagecreatefrom' . $types[$originalType], $original);
- if (function_exists('imagecreatetruecolor') && ($temp = imagecreatetruecolor($resizedWidth, $resizedHeight)))
- {
- imagecopyresampled($temp, $image, 0, 0, $clipX, $clipY, $resizedWidth, $resizedHeight, $originalWidth, $originalHeight);
- }
- else
- {
- $temp = imagecreate($resizedWidth, $resizedHeight);
- imagecopyresized($temp, $image, 0, 0, $clipX, $clipY, $resizedWidth, $resizedHeight, $originalWidth, $originalHeight);
- }
- call_user_func('image' . $types[$originalType], $temp, $resized);
- }
- }
- }
which re-sizes the image properly (thanks to Coppermine Photo Gallery from which I borrowed re-sizing code).
That’s all. Please try and let me know how it worked for you.
Thanks

Wouldn’t it be cleaner to put everything into the helper? Or is there a special reason for using a controller for the resizing?
There is no special reason for using a controller for re-sizing. The idea behind it is http://www.ad7six.com/entries/view/69/Generic-File-Upload-Behavior
FWIW I agreed about doing everything in the helper!