ashley sheridan.co.uk

Smart Image Resizing

When creating any sort of dynamic gallery there is always the issue of creating thumbnails. This is not a problem if all of the source images are the same size, but with a dynamic gallery that cannot be guaranteed. Sure, you could leave instructions that images must be of a certain width and height, and reject anything that doesn't fit, but isn't it nicer to create smart thumbnails from any size and orientation of image?

I wrote this function as a solution to that problem. It determines the proportions of the image you are using, and uses a clever crop and resize in order to pick the best parts of the image.

Portrait silouette of a person in profileWith a portrait photo, the focal point is usually in the top region of the image, aligned horizontally to the middle. This function will then crop the area at the top of the image if it has to crop.

Landscape silouette of some mountainsA landscape image tends to have the focal point in the center, both horizontally and vertically, so this function crops from the center if it has to.

So, here's the code:

  1. function createResizedImage($url, $newUrl, $width, $height)
  2. {
  3.   list($width_orig, $height_orig) = getimagesize($url);
  4.   if(($width / $height) < ($width_orig / $height_orig))
  5.   {
  6.     // landscape
  7.     $ratio = $width / $height;
  8.     $image_p = imagecreatetruecolor($width, $height);
  9.     $image = imagecreatefromjpeg($url);
  10.     imagecopyresampled($image_p, // dst_im
  11.         $image, // src_im
  12.         0, // dst_x
  13.         0, // dst_y
  14.         ($width_orig / 2) - ($height_orig * $ratio) / 2, // src_x
  15.         0, // src_y
  16.         $width, // dst_w
  17.         $height, // dst_h
  18.         $height_orig * $ratio, // src_w
  19.         $height_orig); // src_h
  20.   }
  21.   else
  22.   {
  23.     // portrait
  24.     $ratio = $height / $width;
  25.     $image_p = imagecreatetruecolor($width, $height);
  26.     $image = imagecreatefromjpeg($url);
  27.     imagecopyresampled($image_p, // dst_im
  28.         $image, // src_im
  29.         0, // dst_x
  30.         0, // dst_y
  31.         0, // src_x
  32.         0, // src_y
  33.         $width, // dst_w
  34.         $height, // dst_h
  35.         $width_orig, // src_w
  36.         $width_orig * $ratio); // src_h
  37.   }
  38.   imagejpeg($image_p, $newUrl, 100);
  39. }

And it's called like this:

  1. createResizedImage("image.jpg", "image_thumb.jpg", 150, 100);

The first argument is the source image, the second is the new thumbnail image that you want to create which can contain the path (relative or absolute). You should make sure that you have write permissions for the location of the new image. The last two arguments are the width and height of the new image.

And here is the result on some real photos I've taken (click an image to see the original 640×480 pixel image):