ImageModifier: A PHP Thumbnail Generator

If you have ever written a web application that allows users to upload images, you have encountered the need for automated thumbnail generation. Here’s my version.

I’ve placed a few static methods at the top to simplify the process a bit. The whole script is commented pretty heavily so you should be able to figure it out.

On-the-Fly Resizing

To load an image in, constrain it to a 500×500 bounding box, and render it directly to the browser:

<?php require('lib/ImageModifier.php'); ImageModifier::ResizeAndRender('path/to/source.jpg', 500); ?>

You can even offer the file for download just by adding ‘true’ at the end of the method call:

<?php require('lib/ImageModifier.php'); ImageModifier::ResizeAndRender('path/to/source.jpg', 500,true); ?>

Saving Resized Files on the Server

On-the-fly resizing isn’t exactly the most optimal solution for a public views. Each request will require the image to be loaded, resampled, and passed. Any more than one or two concurrent connections could bring your server down to a crawl. Instead, you can cache the images by saving the outputted image to a folder on the server. Just make sure that you give Apache write permission to the destination directory.

<?php require('lib/ImageModifier.php'); ImageModifier::ResizeAndSave('path/to/source.jpg', 500, 'path/to/resized/destination.jpg'); ?>

Download & Code

You can download the code or check it out below.

<?php class ImageModifier {         private $filename;     private $width;     private $height;     private $type;     private $type_whitelist = array(1,2,3);     private $image;         #     # ResizeAndSave     # -------------------------------------------------------------------------     # Loads, resizes, and saves an image as a single batch operation.     #     # Parameters     #   - string source: The source image to load.     #   - int|float bounds: The bounds to resize within. If a fractional number     #       less than one is passed, it is interpreted as the percentage to     #       resize to. Otherwise, it is interpreted as the bounding box size.     #   - string destination: The destination path and filename to save to.     #         public static function ResizeAndSave($source, $bounds, $destination) {         $temp = new ImageModifier;                 $temp->load($source);         $temp->resize($bounds);         $temp->save($destination);                 unset($temp);     }         #     # ResizeAndRender     # -------------------------------------------------------------------------     # Loads, resizes, and saves an image as a single batch operation.     #     # Parameters     #   - string source: The source image to load.     #   - int|float bounds: The bounds to resize within. If a fractional number     #       less than one is passed, it is interpreted as the percentage to     #       resize to. Otherwise, it is interpreted as the bounding box size.     #   - bool download: Optional. Offers the image for download instead of     #       a direct render.     #         public static function ResizeAndRender($source, $bounds, $download=false) {         $temp = new ImageModifier;                 $temp->load($source);         $temp->resize($bounds);         $temp->render($download);                 unset($temp);     }         #     # load     # -------------------------------------------------------------------------     # Loads an external image from the filestystem, sets class properties, and     # creates an image resource.     #     # Parameters     #   - string file: The path and filename of the source image.     #         public function load($file) {         if(file_exists($file) && is_readable($file)) {             $imagesize = @getimagesize($file);                         if(!empty($imagesize)) {                 if(isset($imagesize[2]) && in_array($imagesize[2], $this->type_whitelist)) {                     $this->filename = $file;                     $this->width = $imagesize[0];                     $this->height = $imagesize[1];                     $this->type = $imagesize[2];                                         $this->imageCreate();                 }             }         }     }         #     # imageCreate     # -------------------------------------------------------------------------     # Creates the image resource used to store the source image for resizing.     #     # Parameters     #   - none     #         private function imageCreate() {         switch($this->type) {             case 1:                 $this->image = imageCreateFromGIF($this->filename);                 break;             case 2:                 $this->image = imageCreateFromJPEG($this->filename);                 break;             case 3:                 $this->image = imageCreateFromPNG($this->filename);                 break;         }     }         #     # resize     # -------------------------------------------------------------------------     # Resizes and resamples the image.     #     # Parameters     #   - int|float bounds: The bounds to resize within. If a fractional number     #       less than one is passed, it is interpreted as the percentage to     #       resize to. Otherwise, it is interpreted as the bounding box size.     #         public function resize($bounds) {         if($bounds < 1) {             $percent =& $bounds;         }         else {             $percent = ($this->width > $this->height)                 ? $bounds / $this->width                 : $bounds / $this->height;         }                 $newWidth = $this->width * $percent;         $newHeight = $this->height * $percent;                 $newImage = imageCreateTrueColor($newWidth, $newHeight);                 imageCopyResampled(                 $newImage,                 $this->image,                 0, 0, 0, 0,                 $newWidth,                 $newHeight,                 $this->width,                 $this->height             );                 $this->image = $newImage;     }         #     # render     # -------------------------------------------------------------------------     # Passes the image to the browser.     #     # Parameters     #   - bool download: Optional. Offers the image for download instead of     #       a direct render.     #            public function render($download=false) {         header('Content-type: '.image_type_to_mime_type($this->type));                 if($download) {             header('Content-Disposition: attachment; filename="'.basename($this->filename).'"');         }                 switch($this->type) {             case 1:                 imageGIF($this->image);                 break;             case 2:                 imageJPEG($this->image);                 break;             case 3:                 imagePNG($this->image);                 break;         }     }         #     # save     # -------------------------------------------------------------------------     # Saves the resized image to the filesystem.     #     # Parameters     #   - string filename: The path and filename of the saved image.     #         public function save($filename) {         switch($this->type) {             case 1:                 @imageGIF($this->image, $filename);                 break;             case 2:                 @imageJPEG($this->image, $filename);                 break;             case 3:                 @imagePNG($this->image, $filename);                 break;         }     }     } ?>

This entry was posted on Monday, March 19th, 2007 at 11:39 am and is filed under PHP. Both comments and pings are currently closed.

5 Responses to ImageModifier: A PHP Thumbnail Generator

Josh:

On March 19th, 2007 at 1:35 pm #

solid piece of work, I’m going to play with this when i get home.

mikeg:

On March 20th, 2007 at 6:48 am #

Let me know what you think. If there are any features you want added or any suggestions for improvement, please post them here.

brian:

On March 20th, 2007 at 4:09 pm #

I’m not sure if ‘outputted’ is a word. Consider ‘generated.’ (Hmm… my spellchecker doesn’t seem to mind. Looks odd to me, though.) Also, maybe change ‘true’ to ‘download’ in the method call so the code makes more sense when you look at it six months later. Otherwise, looks good. You do all the hard work, I’ll just nitpick. :-)

C.Barr:

On April 2nd, 2007 at 9:07 pm #

Dude, totally amazing. I’ve been looking all over for a decent way to resize uploaded images for my CMS, and this looks like a clear winner! Thanks.

The only grip I have is that it seems to break when I use a very large image, like 1.3MB. And knowing the people I make sites for that will use my CMS, they will try and upload gigantic images sometimes.

it says:
Fatal error: Allowed memory size of 12582912 bytes exhausted (tried to allocate 2576 bytes) in /home/ejmedia/public_html/cms/includes/ImageModifier.php on line 101

Any way to get this so I can edit the file size?

C.Barr:

On April 25th, 2007 at 4:06 pm #

As a followup upon using it more in my CMS, the quality of images saved out form this are a bit pixelated looking. it would be nice to include a way to adjust the quality of the outputted image (yes I used “outputted” as well).

Comments are closed. Sorry.

Site Stuff

Pages

Projects

Archives

Categories