Resize an image (on the fly) & keep its aspect ratio using GD
by Gabriel on 28/09/08 at 9:17 am
Greetings! Subscribe to my RSS feed or get my latest post directly in your mailbox. Thanks for visiting!
Hello coders,
This is a PHP Class useful if you need to resize images keeping their aspect ratio, using the GD Library. The new height is calculated proportionally to the new width’s size and reverse. For instance you have an image with the following dimensions: width – 1000, height – 800. Its thumbnail with a width of 250 will have the height of 200 (the ratio is kept). Here’s the class (I will explain you how it works below):
resize.image.class.php
<?php
/*
------------------------------------------------------------------------------------
Credits: Bit Repository
Source URL: http://www.bitrepository.com/web-programming/php/resizing-an-image.html
------------------------------------------------------------------------------------
*/
class Resize_Image {
var $image_to_resize;
var $new_width;
var $new_height;
var $ratio;
var $new_image_name;
var $save_folder;
function resize()
{
if(!file_exists($this->image_to_resize))
{
exit("File ".$this->image_to_resize." does not exist.");
}
$info = GetImageSize($this->image_to_resize);
if(empty($info))
{
exit("The file ".$this->image_to_resize." doesn't seem to be an image.");
}
$width = $info[0];
$height = $info[1];
$mime = $info['mime'];
/* Keep Aspect Ratio? */
if($this->ratio)
{
$thumb = ($this->new_width < $width && $this->new_height < $height) ? true : false; // Thumbnail
$bigger_image = ($this->new_width > $width || $this->new_height > $height) ? true : false; // Bigger Image
if($thumb)
{
if($this->new_width >= $this->new_height)
{
$x = ($width / $this->new_width);
$this->new_height = ($height / $x);
}
else if($this->new_height >= $this->new_width)
{
$x = ($height / $this->new_height);
$this->new_width = ($width / $x);
}
}
else if($bigger_image)
{
if($this->new_width >= $width)
{
$x = ($this->new_width / $width);
$this->new_height = ($height * $x);
}
else if($this->new_height >= $height)
{
$x = ($this->new_height / $height);
$this->new_width = ($width * $x);
}
}
}
// What sort of image?
$type = substr(strrchr($mime, '/'), 1);
switch ($type)
{
case 'jpeg':
$image_create_func = 'ImageCreateFromJPEG';
$image_save_func = 'ImageJPEG';
$new_image_ext = 'jpg';
break;
case 'png':
$image_create_func = 'ImageCreateFromPNG';
$image_save_func = 'ImagePNG';
$new_image_ext = 'png';
break;
case 'bmp':
$image_create_func = 'ImageCreateFromBMP';
$image_save_func = 'ImageBMP';
$new_image_ext = 'bmp';
break;
case 'gif':
$image_create_func = 'ImageCreateFromGIF';
$image_save_func = 'ImageGIF';
$new_image_ext = 'gif';
break;
case 'vnd.wap.wbmp':
$image_create_func = 'ImageCreateFromWBMP';
$image_save_func = 'ImageWBMP';
$new_image_ext = 'bmp';
break;
case 'xbm':
$image_create_func = 'ImageCreateFromXBM';
$image_save_func = 'ImageXBM';
$new_image_ext = 'xbm';
break;
default:
$image_create_func = 'ImageCreateFromJPEG';
$image_save_func = 'ImageJPEG';
$new_image_ext = 'jpg';
}
// New Image
$image_c = ImageCreateTrueColor($this->new_width, $this->new_height);
$new_image = $image_create_func($this->image_to_resize);
ImageCopyResampled($image_c, $new_image, 0, 0, 0, 0, $this->new_width, $this->new_height, $width, $height);
if($this->save_folder)
{
if($this->new_image_name)
{
$new_name = $this->new_image_name.'.'.$new_image_ext;
}
else
{
$new_name = $this->new_thumb_name(basename($this->image_to_resize)).'_resized.'.$new_image_ext;
}
$save_path = $this->save_folder.$new_name;
}
else
{
/* Show the image without saving it to a folder */
header("Content-Type: ".$mime);
$image_save_func($image_c);
$save_path = '';
}
$process = $image_save_func($image_c, $save_path);
return array('result' => $process, 'new_file_path' => $save_path);
}
function new_thumb_name($filename)
{
$string = trim($filename);
$string = strtolower($string);
$string = trim(ereg_replace("[^ A-Za-z0-9_]", " ", $string));
$string = ereg_replace("[ tnr]+", "_", $string);
$string = str_replace(" ", '_', $string);
$string = ereg_replace("[ _]+", "_", $string);
return $string;
}
}
?>
Here’s an example of how you can use this class:
<?php
include 'resize.image.class.php';
$image = new Resize_Image;
$image->new_width = 200;
$image->new_height = 200;
$image->image_to_resize = "/home/mysite.com/public_html/images/sunset_wallpaper.jpg"; // Full Path to the file
$image->ratio = true; // Keep Aspect Ratio?
// Name of the new image (optional) - If it's not set a new will be added automatically
$image->new_image_name = 'sunset_wallpaper_thumbnail';
/* Path where the new image should be saved. If it's not set the script will output the image without saving it */
$image->save_folder = 'thumbs/';
$process = $image->resize();
if($process['result'] && $image->save_folder)
{
echo 'The new image ('.$process['new_file_path'].') has been saved.';
}
?>
How to invoke this class to generate thumbnails in a HTML page?
This class has an advantage: you can resize images ‘on the fly’ with it. This way you don’t have to necessarily save the resized image on the server. You can just output it. Here’s how you can call this class from a HTML page without using any PHP code in it:
demo.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> Show Resized Image </TITLE> <META NAME="Author" CONTENT="Bit Repository"> <META NAME="Keywords" CONTENT="src, image, resize, on the fly"> <META NAME="Description" CONTENT="Display a resized image"> </HEAD> <BODY> <IMG SRC="resize_image.php?image=sunset.jpg&new_width=200&new_height=200"> </BODY> </HTML>
As you can see, the resize_image.php script is called. Some info is needed to make the resize: original image (’image’), a width (’new_width’) and a height (’new_height’). In many cases, if the ‘ratio aspect’ is enabled, you can specify only one measurement. The new dimensions will be calculated based on whether you choose: width or height. Here’s the resize_image.php script:
resize_image.php
<?php
set_time_limit(10000);
error_reporting(E_ALL ^ E_NOTICE);
include 'resize.image.class.php';
$resize_image = new Resize_Image;
// Folder where the (original) images are located with trailing slash at the end
$images_dir = 'images/';
// Image to resize
$image = $_GET['image'];
/* Some validation */
if(!@file_exists($images_dir.$image))
{
exit('The requested image does not exist.');
}
// Get the new with & height
$new_width = (int)$_GET['new_width'];
$new_height = (int)$_GET['new_height'];
$resize_image->new_width = $new_width;
$resize_image->new_height = $new_height;
$resize_image->image_to_resize = $images_dir.$image; // Full Path to the file
$resize_image->ratio = true; // Keep aspect ratio
$process = $resize_image->resize(); // Output image
?>

BitRepository RSS Feed.Please spread the word! |
|

9 Comments
Cropping a rectangle image to square using GD | PHP Library
Oct 1st, 2008
[...] The class checks if the image is already a square. If it is, it will output a message to the user. If it’s not it will calculate the necessary coordinates and crop it: to left, center or right (default is ‘center’). [...]
Mobile Image Replacement — Bryan Rieger
Nov 14th, 2008
[...] class we’re using to resize images (requires GD) doesn’t do a particularly good job of compressing the resulting images. Ideally [...]
Nash
Jan 2nd, 2009
Hello,
Use this script to resize image to differect aspect ratio:
http://nashruddin.com/Resize_Image_to_Different_Aspect_Ratio_on_the_fly
Nash
Larry P
Feb 21st, 2009
Nice work on this. But there is one problem I found. If you choose to keep the aspect ratio but select a width and height one of which is larger than orig and other smaller than orig the logic for keeping the ratio fails. Here’s a simplification that works. Note that the logic is the same whether the new image is going to be larger or smaller.
/* Keep Aspect Ratio? */
if($this->ratio)
{
// if preserving the ratio, only new width or new height
// is used in the computation. if both
// are set, use width
if (isset($this->new_width))
{
$factor = (float)$this->new_width / (float)$width;
$this->new_height = $factor * $height;
}
else if (isset($this->new_height))
{
$factor = (float)$this->new_height / (float)$height;
$this->new_width = $factor * $width;
}
else
exit(”neither new height or new width has been set”);
}
Gabriel
Mar 8th, 2009
Thanks, Larry! I’ve tested it and really works smoothly.
Brian
Mar 13th, 2009
Exactly what I’ve been looking for.
Mike
Mar 21st, 2009
I have one question. Is it posible to create an function and point the source to it, instead of the approach in the example?
example:
to use:
<code><?php
print "<IMG SRC=\"".resize_image(sunset.jpg,200,200)."\"">";
?>
</code>
<code>
insead of:
<IMG SRC="resize_image.php?image=sunset.jpg&new_width=200&new_height=200">
</code>
p.s.: aaaaa, this stupid code. sorry for spaming. I ask moderator to delete above posts.
Rive Backend Flex webapp prerelease | Rive.be | Blog
May 4th, 2009
[...] upload, on the fly resized by PHP5 in the [...]
Mattias
May 25th, 2009
There is an another error or additional function:
I want to use this parameters:
$image->new_width = 128;
$image->new_height = 100;
And if i upload a picture (500*500), it produces a128*128 pixel thumbinalk, but I set 100px for maximal height, so i want a 100*100px image in this case.
Solution:
PART ONE:
function resize()
{
##########################
## Mattias’s extension
##########################
$eredeti_w = $this->new_width;
$eredeti_h = $this->new_height;
##########################
## Mattias’s extension END
##########################
.
.
.
PART TWO:
##########################
## Mattias’s extension
##########################
if($this->new_height > $eredeti_h)
{
$faktor = $eredeti_h / $this->new_height;
$this->new_height = $this->new_height * $faktor;
$this->new_width = $this->new_width * $faktor;
}
if($this->new_width > $eredeti_w)
{
$faktor = $eredeti_w / $this->new_width;
$this->new_height = $this->new_height * $faktor;
$this->new_width = $this->new_width * $faktor;
}
##########################
## Mattias’s extension END
##########################
// New Image
$image_c = ImageCreateTrueColor($this->new_width, $this->new_height);
.
.
.
Only need to insert code between the comment…
Leave a Comment