Resize an Image (on the fly) & Keep its Aspect Ratio using PHP and GD

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/resize-an-image-keeping-its-aspect-ratio-using-php-and-gd.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?

Improved, thanks to Larry
*/

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”);
}

// 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;
	}
}
?>

Variables Info

$image_to_resize – Here we set the full path (i.e. /home/www.mysite.com/public_html/images/myimage.jpg) to the image we wish to resize. If the image is in the same folder with the class, then you can just set the filename as the path (i.e. mywallpaper.jpg).

The $new_width & $new_height are the new dimensions for the resized image.

$ratio – Do you wish to keep the image’s ratio aspect after resize? If it’s set to true it will calculate the new dimensions based on the new width (if it’s bigger than the height) or the new height (if it’s bigger than width).

$new_image_name – It’s used to set a name for the new resized image. If it’s not set a name will be assigned automatically.

$save_folder – The path to the folder where the new image will be saved. Make sure it’s writable (0777). It no folder is set the new image will show in the browser without being saved.

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
?>

Comment via Facebook

comments

36 Comments

  1. Gianluca says

    I did this: ( as the imageMagick 20×30> syntax)

    if ($this->ratio) {
    if ( ($width / $height) > ($this->new_width / $this->new_height) ) {
    $this->new_height = ($height * ($this->new_width / $width));
    }
    else {
    $this->new_width = ($width * ($this->new_height / $height));
    }
    }

  2. Hans says

    Hi, i’m using this script for a while and returning a good result, but there is a problem when i try to upload .GIF file, the animated gif stopped(doesn’t work) when it was re-sized. any clue ?

  3. says

    i use a page header location loop so every time the page is refreshed is do this
    new_width = 120;
    $image->new_height = 160;

    $image->image_to_resize = $bulk;// Full Path to the file

    $image->ratio = false; // Keep Aspect Ratio?

    // Name of the new image (optional) – If it’s not set a new will be added automatically

    $image->new_image_name = $filename;

    /* 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 = $new_location.$category.”/thumbs/” ;

    $process = $image->resize();
    if($process[‘result’] && $image->save_folder)
    {
    echo ‘The new thumb (‘.$process[‘new_file_path’].’) has been saved.';
    }
    but for some strange reason sometimes the logo is not generate , i have an idea to use a if for that but i need some info for you script im beginer in to php and i need dome help if it is posible the idea will be something like this
    if some var = false then insert in to sql 1 else insert in to sql 0 header location this file :P

  4. Pierre says

    Thanks for the code.

    I want to use this script for mobile site, meaning the images (logo) would resize on the fly for any mobile phone.

    responsive layout wont support all screen sizes.

    what i want to know is how to set the generated image size based on the width or height of a mobile screen?

    as i see it, you need to define the output size for the script to generate the new image. but i want it to generate an image according to the size of the screen.

    Id have to use jQuery to get.width and use that outpu to determine the width of the php generated image (with aspect ratio on)

    Any ideas?

  5. viorel says

    this script is no longer work for me. and is work fine for about 2 mounts now i have big problem.
    fist pages display in blank but when i remove the include is worked.
    mai it be the host changed some thing what do you think about this ?
    and is posible to fix this sheet.

  6. Hemali says

    I used this class file to resize my image. But I found an error to insert bmp and tif file.
    my file type is bmp and as i print $type value that was "x-ms-bmp" and for tif image the $type value was "tif" as it is not avaliavle in switch case. What to do? can anybody help me?
    Your reply will be appriciate.
    Thank you

Trackbacks

Leave a Reply

Your email address will not be published. Required fields are marked *