PHP Thumbnail Creation Tutorial

This tutorial will explain how to take any image and proportionally shrink it to any size you define.

The three main goals of this function are:

  1. Shrink an image to a defined size
  2. Keep the new image proportional to the old image
  3. Create the new image in the same directory as the old image with a defined prefix (i.e. 'tn_')

And here we go!

Please note: This requires the PHP ImageGD Library. Read more about this by clicking here. You will also find a complete reference for all image manipulation functions at that page.

Step 1: Enter Function

function MakeThumbnail($name, $max_w, $max_h, $prefix) {

You can pass four parameters into the function:

  1. name: The filename of the image
  2. max_w: The maximum desired width of the resized image
  3. max_h: The maximum desired height of the resized image
  4. prefix: Prefix for the new filename (ex. 'tn_')

Step 2: Make sure its an image and copy the image

	//Split name by '.' character in order to obtain the extension
	$system=explode(".",$name);
	
	//The file must be a JPEG, PNG, or GIF. Otherwise, the function returns nothing.
	if (preg_match("/jpg|jpeg|JPG|JPEG/",$system[1])){
		$src_img=imagecreatefromjpeg($name);
	} else if (preg_match("/png|PNG/",$system[1])){
		$src_img=imagecreatefrompng($name);
	} else if (preg_match("/gif|GIF/",$system[1])){
		$src_img=imagecreatefromgif($name);
	} else {
		return;
	}

Next, we want to make sure that only images are passed into this function.

In order to obtain the extension of the filename, we use php's explode function with delimiter ".", which will then split the file name into an array. Array position 1 will contain the file extension.

Then, we check to see if the file extension is correct. If it is, we use php's 'imagecreatefrom' functions to assign a copy of this image to the $src_img variable.

Step 3: Get the new dimensions

	//Obtain the width and height of the new images
	$old_w=imageSX($src_img);
	$old_h=imageSY($src_img);

The imageSX and imageSY functions allow us to determine the height and width of the old image. This will be extremely important in proportionally resizing the image.

	//Find the smaller dimension of the max width and height for the new image
	if ($max_w > $max_h)
		$max_h = $max_w;
	else if ($max_h > $max_w)
		$max_w = $max_h;

Think of the max width and max height as a box in which you wish to resize the image. Lets say max_w is 250 and max_h is 200. In order to fit the entire image into this box, we have to make the max_w and max_h equal to the lower of the two numbers. Here's an example of why this needs to happen.

Let's say we have an image that is 500px x 400px wide. In order to fit this image into our 250px x 200px box, we need to make it be 200px high. If we did not do this, the image would fit snugly in terms of width, but the bottom of the image would be cut off.

	//Obtain new dimensions
	if ($old_w > $old_h) {
		$thumb_w=$max_w;
		$thumb_h=$old_h*($max_w/$old_w);
	}
	if ($old_w < $old_h) {
		$thumb_w=$old_w*($max_h/$old_h);
		$thumb_h=$max_h;
	}
	if ($old_w == $old_h) {
		$thumb_w=$max_w;
		$thumb_h=$max_h;
	}

This is the heart of determining the new width and height of the new image. This provides new, proportional image dimensions. Let's show an example with the following variables:

  • Old Image: 500px wide. 400px high.
  • New Image: 200px wide. 200px high.

This first thing you might note is that the new and old image have different proportions. Our function will take care of that. Now, let's proceed through the code above.

Since the old width is greater than the old height (500 > 400), we set the new width to 200px. We want the height to be proportional to the height of the old image. In this case, we want the height to be 160px. In order to obtain this number, we use the following methodology.

New height = old height * (max width / old width)

The ratio of max width over old width tells us how much the image will shrink. We multiply this to the old height of the image to determine the new height. In this case, 200/500 = .4, and 400 * .4 = 160. This means that the new image will be 40% the size of the old image.

Therefore, we got the right proportion! A 500x400 image has the same proportion as a 200x160 image.

Step 4: Get the new filename

	//Split apart file name by forward slashes
	$f = explode("/", $system[0]);
	for ($i=0; $i

Now that we have the proportions of our new image, we want to obtain what the filename of the new image will be. If the filename already exists, we return nothing as we do not want to overwrite another file.

First, we split the filename (minus the extension) into an array. We then put the directories into one variable and the actual filename into another variable. For example:

Filename: dir1/dir2/dir3/filename
$filefolders = 'dir1/dir2/dir3/'
$fname = 'filename'

Then, we can paste everything together with the prefix in front of the filename.

Here is our new filename: dir1/dir2/dir3/tn_filename.jpg

Step 5: Create the new image

	$dst_img=imagecreatetruecolor($thumb_w,$thumb_h);
	imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_w,$old_h);  

The imagecreatetruecolor and imagecopyresampled functions are the true power behind the creation of the new image

imagecreatetruecolor creates a placeholder image with the width and height of the new image.

imagecopyresampled copies the old image onto the placeholder image. It does so by taking a copy of the original image, shrinking it to the desired size, and outputting the new image to onto the placeholder.

Step 6: Output the image to the new filename

	if (preg_match("/png|PNG/",$system[1]))
	{
		imagepng($dst_img,$filename); 
	} else if (preg_match("/gif|GIF/",$system[1])) {
		imagegif($dst_img,$filename); 
	} else {
		imagejpeg($dst_img,$filename); 
	}
	imagedestroy($dst_img); 
	imagedestroy($src_img);
	return $filename;

Depending on the extension of the image, the function imagepng, imagegif, or imagejpeg will create a new file for the given image in $dst_src. This completes the file copy. All that needs to be done is garbage cleanup and returning the filename.

That's all there is to it, and now you can create thumbnails of any image you wish!

Here's the entire function without breaks for reference:

function MakeThumbnail($name, $max_w, $max_h, $prefix = 'tn_') {
	
	//Split name by '.' character in order to obtain the extension
	$system=explode(".",$name);
	
	//The file must be a JPEG, PNG, or GIF. Otherwise, the function returns nothing.
	if (preg_match("/jpg|jpeg|JPG|JPEG/",$system[1])){
		$src_img=imagecreatefromjpeg($name);
	} else if (preg_match("/png|PNG/",$system[1])){
		$src_img=imagecreatefrompng($name);
	} else if (preg_match("/gif|GIF/",$system[1])){
		$src_img=imagecreatefromgif($name);
	} else {
		return;
	}
	
	//Obtain the width and height of the new images
	$old_w=imageSX($src_img);
	$old_h=imageSY($src_img);
	
	//Find the smaller dimension of the max width and height for the new image
	if ($max_w > $max_h)
		$max_h = $max_w;
	else if ($max_h > $max_w)
		$max_w = $max_h;
	
	//Obtain new dimensions
	if ($old_w > $old_h) {
		$thumb_w=$max_w;
		$thumb_h=$old_h*($max_w/$old_w);
	}
	if ($old_w < $old_h) {
		$thumb_w=$old_w*($max_h/$old_h);
		$thumb_h=$max_h;
	}
	if ($old_w == $old_h) {
		$thumb_w=$max_w;
		$thumb_h=$max_h;
	}
	
	//Split apart file name by forward slashes
	$f = explode("/", $system[0]);
	for ($i=0; $i<count($f);$i++) {
		if ($i == count($f) - 1) 
			$fname = $f[$i];
		else
			$filefolders .= $f[$i]."/";
	}
	
	//Put prefix in front of filename
	$filename = $filefolders.$prefix.$fname.".".$system[1];
	if(file_exists($filename)) {
		return $filename;
	}

	//Create new image
	$dst_img=imagecreatetruecolor($thumb_w,$thumb_h);

	imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_w,$old_h);  
	if (preg_match("/png|PNG/",$system[1]))
	{
		imagepng($dst_img,$filename); 
	} else if (preg_match("/gif|GIF/",$system[1])) {
		imagegif($dst_img,$filename); 
	} else {
		imagejpeg($dst_img,$filename); 
	}
	
	//Garbage cleanup
	imagedestroy($dst_img); 
	imagedestroy($src_img);
	return $filename;
}

About the Author

Ben has been seriously working with websites since he was about 15, when he created a dynamic website to list results and user profiles for the Cross Country and Track and Field community in his county. Ever since, he has been enamored with web...

 
blog rss banner
 

Categories

View All

Testimonials

Mike and his team have taken over a web site that was limping along, with an extensive list of problems and a weak design.  They jumped into the task and are rapidly disposing of issues that had...

Laura Perry, Marketing Director
Whiteford | Taylor | Preston

“Unleashed Technologies is a pleasure to work with. We needed an unusual, non-cookie-cutter web site on a very tight schedule, and Unleashed Technologies delivered.

Paul Jakubik
PureDiscovery Corporation