Resize an Image on the Fly with PHP

I have created three different functions that use PHP's GD Image Functions to resize images on the fly. The first crops images to fit to the new size so that the aspect ratio is maintained. The second allows you to set a maximum width or height and then shrinks the image to fit those specifications. And, the third forces the image into a specific size, even if that means that the aspect ratio is changed. Additionally, I've constructed a function that loads and saves the images (in JPEG, GIF, PNG, or BMP format) and provides detailed error reporting in case something goes wrong. We'll start with the examples first and then explain how everything works.

Examples

PenguinThey say a picture is worth a thousand words. Well, here's a few pictures... you can decide how many words they're worth. The penguin to the left is the image we'll start with. He's 111 x 193 pixels. In all three examples, we use the resize_image helper function to load up and save the actual image files.


Penguinresize_image('crop','penguin.jpg','penguin_crop.jpg',100,100);

As you can see, this poor penguin was cropped into a smaller image, 100 x 100 pixels, using the resize_image_crop function.


Penguinresize_image('max','penguin.jpg','penguin_max.jpg',100,100);

With the resize_image_max function, we specified that this penguin would have a max height or width of 100 pixels. Since the original is taller than it is wide, the new penguin is 100 pixels tall, but only 57 pixels wide.


Penguinresize_image('force','penguin.jpg','penguin_force.jpg',100,100);

Finally, we created this squished penguin using the resize_image_force function. He is 100 x 100 pixels, but because no cropping occured, the original aspect ratio was abandoned.


resize_image_crop($image,$width,$height)

This function generates a new image in the dimensions you specify, maintaining the aspect ratio by cropping when necessary.

1.   <?php
2.   
3.   function resize_image_crop($image,$width,$height) {
4.   	$w = @imagesx($image); //current width
5.   	$h = @imagesy($image); //current height
6.   	if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
7.   	if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
8.   	
9.   	//try max width first...
10.  	$ratio = $width / $w;
11.  	$new_w = $width;
12.  	$new_h = $h * $ratio;
13.  	
14.  	//if that created an image smaller than what we wanted, try the other way
15.  	if ($new_h < $height) {
16.  		$ratio = $height / $h;
17.  		$new_h = $height;
18.  		$new_w = $w * $ratio;
19.  	}
20.  	
21.  	$image2 = imagecreatetruecolor ($new_w, $new_h);
22.  	imagecopyresampled($image2,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
23.  
24.  	//check to see if cropping needs to happen
25.  	if (($new_h != $height) || ($new_w != $width)) {
26.  		$image3 = imagecreatetruecolor ($width, $height);
27.  		if ($new_h > $height) { //crop vertically
28.  			$extra = $new_h - $height;
29.  			$x = 0; //source x
30.  			$y = round($extra / 2); //source y
31.  			imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
32.  		} else {
33.  			$extra = $new_w - $width;
34.  			$x = round($extra / 2); //source x
35.  			$y = 0; //source y
36.  			imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
37.  		}
38.  		imagedestroy($image2);
39.  		return $image3;
40.  	} else {
41.  		return $image2;
42.  	}
43.  }
44.  
45.  ?>

resize_image_max($image,$max_width,$max_height)

This function checks to see if your image exceeds either the max width or the max height specified and, if so, resizes the image while maintaining the aspect ratio.

1.   <?php
2.   
3.   function resize_image_max($image,$max_width,$max_height) {
4.   	$w = imagesx($image); //current width
5.   	$h = imagesy($image); //current height
6.   	if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
7.   
8.   	if (($w <= $max_width) && ($h <= $max_height)) { return $image; } //no resizing needed
9.   	
10.  	//try max width first...
11.  	$ratio = $max_width / $w;
12.  	$new_w = $max_width;
13.  	$new_h = $h * $ratio;
14.  	
15.  	//if that didn't work
16.  	if ($new_h > $max_height) {
17.  		$ratio = $max_height / $h;
18.  		$new_h = $max_height;
19.  		$new_w = $w * $ratio;
20.  	}
21.  	
22.  	$new_image = imagecreatetruecolor ($new_w, $new_h);
23.  	imagecopyresampled($new_image,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
24.  	return $new_image;
25.  }
26.  
27.  ?>

resize_image_force($image,$width,$height)

This function generates a new image in the dimensions you specify without cropping, so the aspect ratio may be altered.

1.   <?php
2.   
3.   function resize_image_force($image,$width,$height) {
4.   	$w = @imagesx($image); //current width
5.   	$h = @imagesy($image); //current height
6.   	if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
7.   	if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
8.   
9.   	$image2 = imagecreatetruecolor ($width, $height);
10.  	imagecopyresampled($image2,$image, 0, 0, 0, 0, $width, $height, $w, $h);
11.  
12.  	return $image2;
13.  }
14.  
15.  ?>

resize_image($method,$image_loc,$new_loc,$width,$height)

Those functions all start with an image that has already been opened by the GD Image functions. This next function goes farther and opens up an image file, resizes it according to the method you choose, and then saves it for you. It also displays any errors that are generated in an easy-to-understand way.

1.   <?php
2.   
3.   function resize_image($method,$image_loc,$new_loc,$width,$height) {
4.   	if (!is_array(@$GLOBALS['errors'])) { $GLOBALS['errors'] = array(); }
5.   	
6.   	if (!in_array($method,array('force','max','crop'))) { $GLOBALS['errors'][] = 'Invalid method selected.'; }
7.   	
8.   	if (!$image_loc) { $GLOBALS['errors'][] = 'No source image location specified.'; }
9.   	else {
10.  		if ((substr(strtolower($image_loc),0,7) == 'http://') || (substr(strtolower($image_loc),0,7) == 'https://')) { /*don't check to see if file exists since it's not local*/ }
11.  		elseif (!file_exists($image_loc)) { $GLOBALS['errors'][] = 'Image source file does not exist.'; }
12.  		$extension = strtolower(substr($image_loc,strrpos($image_loc,'.')));
13.  		if (!in_array($extension,array('.jpg','.jpeg','.png','.gif','.bmp'))) { $GLOBALS['errors'][] = 'Invalid source file extension!'; }
14.  	}
15.  	
16.  	if (!$new_loc) { $GLOBALS['errors'][] = 'No destination image location specified.'; }
17.  	else {
18.  		$new_extension = strtolower(substr($new_loc,strrpos($new_loc,'.')));
19.  		if (!in_array($new_extension,array('.jpg','.jpeg','.png','.gif','.bmp'))) { $GLOBALS['errors'][] = 'Invalid destination file extension!'; }
20.  	}
21.  
22.  	$width = abs(intval($width));
23.  	if (!$width) { $GLOBALS['errors'][] = 'No width specified!'; }
24.  	
25.  	$height = abs(intval($height));
26.  	if (!$height) { $GLOBALS['errors'][] = 'No height specified!'; }
27.  	
28.  	if (count($GLOBALS['errors']) > 0) { echo_errors(); return false; }
29.  	
30.  	if (in_array($extension,array('.jpg','.jpeg'))) { $image = @imagecreatefromjpeg($image_loc); }
31.  	elseif ($extension == '.png') { $image = @imagecreatefrompng($image_loc); }
32.  	elseif ($extension == '.gif') { $image = @imagecreatefromgif($image_loc); }
33.  	elseif ($extension == '.bmp') { $image = @imagecreatefromwbmp($image_loc); }
34.  	
35.  	if (!$image) { $GLOBALS['errors'][] = 'Image could not be generated!'; }
36.  	else {
37.  		$current_width = imagesx($image);
38.  		$current_height = imagesy($image);
39.  		if ((!$current_width) || (!$current_height)) { $GLOBALS['errors'][] = 'Generated image has invalid dimensions!'; }
40.  	}
41.  	if (count($GLOBALS['errors']) > 0) { @imagedestroy($image); echo_errors(); return false; }
42.  
43.  	if ($method == 'force') { $new_image = resize_image_force($image,$width,$height); }
44.  	elseif ($method == 'max') { $new_image = resize_image_max($image,$width,$height); }
45.  	elseif ($method == 'crop') { $new_image = resize_image_crop($image,$width,$height); }
46.  	
47.  	if ((!$new_image) && (count($GLOBALS['errors'] == 0))) { $GLOBALS['errors'][] = 'New image could not be generated!'; }
48.  	if (count($GLOBALS['errors']) > 0) { @imagedestroy($image); echo_errors(); return false; }
49.  	
50.  	$save_error = false;
51.  	if (in_array($extension,array('.jpg','.jpeg'))) { imagejpeg($new_image,$new_loc) or ($save_error = true); }
52.  	elseif ($extension == '.png') { imagepng($new_image,$new_loc) or ($save_error = true); }
53.  	elseif ($extension == '.gif') { imagegif($new_image,$new_loc) or ($save_error = true); }
54.  	elseif ($extension == '.bmp') { imagewbmp($new_image,$new_loc) or ($save_error = true); }
55.  	if ($save_error) { $GLOBALS['errors'][] = 'New image could not be saved!'; }
56.  	if (count($GLOBALS['errors']) > 0) { @imagedestroy($image); @imagedestroy($new_image); echo_errors(); return false; }
57.  
58.  	imagedestroy($image);
59.  	imagedestroy($new_image);
60.  	
61.  	return true;
62.  }
63.  
64.  function echo_errors() {
65.  	if (!is_array(@$GLOBALS['errors'])) { $GLOBALS['errors'] = array('Unknown error!'); }
66.  	foreach ($GLOBALS['errors'] as $error) { echo '<p style="color:red;font-weight:bold;">Error: '.$error.'</p>'; }
67.  }
68.  
69.  
70.  
71.  ?>

Comments

Loading…

This post was published on August 4th, 2011 by Robert James Reese in the following categories: Images and PHP. Before using any of the code or other content in this post, you must read and agree to our terms of use.