thumb·nail (noun): A reduced image of a graphic or document page, used in order to view multiple images on a screen simultaneously or to download such images more rapidly.
Almost every site on the internet today, to some extent display images. Be it a Web store, a Photographer or a Designer’s portfolio or a Blog. But it is not always logical to make the site’s viewer download a large image just to press it into a small space with many other similar photos. That’s where thumbnails come in, Thumbnails are pre-generated miniature versions of large photos with small file size, perfect for displaying in gallery view of any website.
Requirements
- Basic knowledge of PHP (Duh!)
- Basic Math Skills
- PHP Installation with the PHP GD Extension enabled.
Lets get Started
I know we are all PHP gurus here and Object Oriented Programming is the way to go, but for the same of simplicity and comfort for PHP beginners the code on this tutorial is written in the procedural way…
(Besides I’m here to teach you how to make thumbnails not OOP)
So first lets start with listing down the different settings which maybe be required to generate a thumbnail…
- Height & Width of the Thumbnail
- Output Format, Quality, Filename
- Background Color
Lets go ahead and declare a function that accepts these as parameters
function thumb( $file, $dest, $height, $width, $output_format, $output_quality, $bg_color ){ //Magic... }
It is often good practice to include default values so here in the updated function declaration:
function thumb( $file, $dest, $height = 150, $width = 180, $output_format = "jpg", $output_quality = 80, $bg_color = array(0,0,0) ){ //Magic... }
Note: Background Color ($bg_color) is a simple array containing RGB values of a color…
Our first objective is to justify the image format and the dimensions of the image, a simple case statement should do the trick… this is part of the body of the thumb() function
//Justify the Image format and create a GD resource $image_info = getimagesize($file); $image_type = $image_info[2]; switch($image_type){ case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break; case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break; case IMAGETYPE_GIF: $image = imagecreatefrompng($file); break; default: die("Image Format not Suppoted"); } $image_width = imagesx($image); $image_height = imagesy($image);
- getimagesize() does a little more than its name, not only does it return the height and width of the image it also returns the type of the image as it’s 3rd index.
- imagecreatefromjpeg(), …gif() , …png() these are GD functions that create an image resource in memory from a file that can be later altered and manipulated with other GD functions.
- imagesx() & imagesy() returns the width and height respectively of a given GD Image resource.
Calculations
First we need to justify the orientation of the image, if landscape mode(width larger than height) we can snap the image to the thumbnail width or if portrait mode (height larger than width) we can snap the image height to the thumbnail height…

Basic Idea
based on the ration of Thumbnail Dimensions to Original Dimensions we can then calculate the new height or width of the image for the thumbnail with these simple math expressions….
Landscape Orientation:
height = (thumbnail width / original width) * original height
Portrait Orientation:
width = (thumbnail height / original height) * original width
BUT THEN!
what if the calculated height or width is larger then the respective dimensions of the thumbnail?
That is why we must do another check to see if that is true and if it is we must then snap the image to the dimension that is larger than the thumbnail and recalculate the other…
ENOUGH TALKING! LETS CODE…
Here you see the totality of the calculate function which we will need to call from inside the thumb() function…
function calculate($height, $width, $image_height, $image_width){ //If Image width is bigger than the Thumbnail Width if($image_width>$height){ //Set Image Width to Thumbnail Width $new["width"] = $width; //Calculate Height according to width $new["height"] = ($new["width"]/$image_width)*$image_height; //If Resulting height is bigger than the thumbnail Height if($new["height"]>$height){ //Set the image Height to THUmbnail Height $new["height"] = $height; //Recalculate width according to height of the thumbnail $new["width"] = ($new["height"]/$image_height)*$image_width; } }else{ $new["height"] = $height; $new["width"] = ($new["height"]/$image_height)*$image_width; if($new["width"]>$width){ $new["width"] = $width; $new["height"] = ($new["width"]/$image_width)*$image_height; } } //Calculate the image position based on the difference between the dimensons of the new image and thumbnail $x = ($width-$new["width"])/2; $y = ($height-$new["height"])/2; return array_merge($new, array("x"=>$x,"y"=>$y)); }
The code is quite self explanatory with all the comments in place… The $x & $y variables contain x & y offsets in order to center the image…
What is the last line doing?
Ans: Its joining the array containing the dimensions of the thumbnail image and another array(declared on spot) containing the x & y offsets and returning the new array…
Back to our thumbnail() Function
Here’s the rest of our thumb() function…
//Get The Calculations $calc = calculate($height, $width, $image_height, $image_width); //Create an Empty image $canvas = imagecreatetruecolor($width, $height); //Load Background color $color = imagecolorallocate($canvas, $bg_color[0], $bg_color[1], $bg_color[2] ); //FIll the Image with the Background color imagefilledrectangle( $canvas, 0, 0, $width, $height, $color ); //The REAL Magic imagecopyresampled( $canvas, $image, $calc["x"], $calc["y"], 0, 0, $calc["width"], $calc["height"], $image_width, $image_height ); //Output output( $canvas, $dest, $output_format, $output_quality );
- On the $canvas variable we are creating an empty GD Image for use as our thumbnail canvas.
- The $color variable registers a color to be used, here we registered the background color that we provided as an array of Red Green & Blue values….
- imagefilledrectangle() fills our canvas with our background color.
- The Real Magic is done by the imagecopyresampled() function, as this function does the positioning and resizing using the calculations we got. (reading it’s documentation is highly advised)
Now what about this output function that we called on the last line?
Well, that function handles the outputting to file feature…
The output() Function
function output($image, $dest, $format, $quality){ switch($format){ case "jpg": imagejpeg($image, $dest, $quality); break; case "gif": imagegif($image, $dest); break; case "png": //Png Quality is measured from 1 to 9 imagepng($image, $dest, round(($quality/100)*9) ); break; } }
The Complete Code
<?php function calculate($height, $width, $image_height, $image_width){ //If Image width is bigger than the Thumbnail Width if($image_width>$height){ //Set Image Width to Thumbnail Width $new["width"] = $width; //Calculate Height according to width $new["height"] = ($new["width"]/$image_width)*$image_height; //If Resulting height is bigger than the thumbnail Height if($new["height"]>$height){ //Set the image Height to THUmbnail Height $new["height"] = $height; //Recalculate width according to height of the thumbnail $new["width"] = ($new["height"]/$image_height)*$image_width; } }else{ $new["height"] = $height; $new["width"] = ($new["height"]/$image_height)*$image_width; if($new["width"]>$width){ $new["width"] = $width; $new["height"] = ($new["width"]/$image_width)*$image_height; } } //Calculate the image position based on the difference between the dimensons of the new image and thumbnail $x = ($width-$new["width"])/2; $y = ($height-$new["height"])/2; return array_merge($new, array("x"=>$x,"y"=>$y)); } function output($image, $dest, $format, $quality){ switch($format){ case "jpg": imagejpeg($image, $dest, $quality); break; case "gif": imagegif($image, $dest); break; case "png": //Png Quality is measured from 1 to 9 imagepng($image, $dest, round(($quality/100)*9) ); break; } } function thumb( $file, $dest, $height = 150, $width = 180, $output_format = "jpg", $output_quality = 80, $bg_color = array(0,0,0) ){ //Justify the Image format and create a GD resource $image_info = getimagesize($file); $image_type = $image_info[2]; switch($image_type){ case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break; case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break; case IMAGETYPE_GIF: $image = imagecreatefrompng($file); break; default: die("Image Format not Suppoted"); } $image_width = imagesx($image); $image_height = imagesy($image); //Get The Calculations $calc = calculate($height, $width, $image_height, $image_width); //Create an Empty image $canvas = imagecreatetruecolor($width, $height); //Load Background color $color = imagecolorallocate($canvas, $bg_color[0], $bg_color[1], $bg_color[2] ); //FIll the Image with the Background color imagefilledrectangle( $canvas, 0, 0, $width, $height, $color ); //The REAL Magic imagecopyresampled( $canvas, $image, $calc["x"], $calc["y"], 0, 0, $calc["width"], $calc["height"], $image_width, $image_height ); //Output output( $canvas, $dest, $output_format, $output_quality ); } //Testing thumb("original.jpg", "thumbnail.jpg"); ?>
to use the code all you have to do is call the thumb() function with appropriate parameters…
A few example useage:
//Larger Thumbnail thumb( "original.jpg", "thumb.jpg", 300, 350 ); //Output GIF thumb( "original.jpg", "thumb.jpg", 300, 350, "gif", 90 ); //White Background thumb( "original.jpg", "thumb.jpg", 300, 350, "gif", 90, array(255,255,255) );
Conclusion
I hope after reading this you got an basic idea of how PHP GD works and I bet with this basic code you can make more advanced libraries written in OO PHP but for now that’s all…
Hi, I am Omran Jamal from Bangladesh, a Student of A-Level, and an Intern at Techbeeo. Though young, I am very enthusiastic about Computers. Taught myself how to code when I was 12 and been coding ever since.
Great tutorial, a zip of the whole package combined will be appreciated. Thanks though for the tutorial. Cheers
Is a Zip really that necessary? I mean on the last part I provided the complete code…
Dude, thanks a lot, I’ve bookmarked this 🙂