PHP resize image on the fly

How to resize an image on the fly with PHP without keeping multiple thumbnails in the server.

When we are uploading an image to server we can create thumbnails for each image for different purposes. But when we are creating thumbnails for each an every image, it will need more server space every time for this unnecessary process.

Now let’s see why we are calling this as a ‘unnecessary process’. The reason for above statement is that we don’t need to create number of thumbnails for each an every image for our needs. We can use the same image for any size of image. In this solution, same image will be rendered in several sizes with the aspect ratio and with the quality that you wish which needs to be there.

In this case, you will be able to render the image through a URL by passing the image name, size of the image, quality of the image and etc.. So all you need to do is put the correct image URL with the correct parameters in the img tag or somewhere else. Most of the websites and systems are using this image rendering method as a technology since it is very helpful for saving server spaces and easy to render any size of image as they wish.

Today we are going to implement this image rendering method with PHP. Following codes will help you to implement this process.

 

Step 01

Following page will grab the URL parameters and pass it to the Image library to render the requested image through the URL.

URL for the below implementation should be like below.

https://example.com/resize-image-on-the-fly.php/?image=image.jpg&size=1000&dimension=width&quality=100

index.php

<?php
require_once("./Image.php");

$default_image ="./default.png";//set a default image
$image_name = "";//name of the requesting image
$size = 1000;//Default size for the image, if image size has not been set
$dimension = "";//Default value is width and you can select this value from width and height 
$quality = 100;//Default image quality 

if(isset($_GET["image"])){ $image_name = $_GET["image"]; }
if(isset($_GET["size"])){ $size = $_GET["size"]; }
if(isset($_GET["dimension"])){ $dimension = $_GET["dimension"]; }
if(isset($_GET["quality"])){ $quality = $_GET["quality"]; }

$image_path = "./".$image_name;

$imgLib = new Image();
$imgLib->export_image($default_image, $image_path, $size, $dimension, $quality);
?>

Step 02

Once it’s called the function ‘export_image’ in the Image library class, image will be rendered with the size of the image which was requested in the URL. Here it’s not going to save the generated image in the server. It’ll be a temporary image which was rendered during the request to the server. Once the response is sent, the generated image will be destroyed. So it won’t need any server space for saving thumbnails.

You will be able to get the idea which has been implemented in this library easily. Full source code is well explained through the code comments to guide you through.

Image.php

<?php
class Image
{	
	/**
	 * @param string default_image - Path for the default image which should be displayed instead of requested image when the requested image does not exist.
	 * @param string path_to_image - Path for the source image
	 * @param string size - Rendering image's width or height which needs to set
	 * @param string dimension - which dimension will be considered as the size of the image. Ex: height
	 * @param string quality - quality for the rendering image as a percentage
	 */
	function export_image($default_image, $path_to_image, $size, $dimension = "width", $quality = 100)
	{
		$valid = false;
		if($this->is_valid_image($path_to_image))
		{
			$valid=true;
		}
		else if($default_image != "" && $this->is_valid_image($default_image))
		{
			$valid=true;
			$path_to_image = $default_image;
		}
		
		if($valid)
		{
			// parse path for the extension
			$info = pathinfo($path_to_image);
			
			list($width, $height, $img) = $this->get_image_width_height($info["extension"], $path_to_image);
			
			if($dimension == "height" || $dimension == "width")
			{
				if($dimension == "height")
				{
					$size=intval($size);
					
					$new_height=$size;
					if($new_height > $height)
					{
						$new_height=$height;
					}
					$new_width=floor($new_height*($width/$height));
				}
				else if($dimension == "width")
				{
					$size=intval($size);
					
					$new_width=$size;
					if($new_width > $width)
					{
						$new_width=$width;
					}
					$new_height=floor($new_width*($height/$width));
				}
			}
			else
			{
				if($width > $height)
				{
					$new_width = $size;
					$new_height=floor($new_width*($height/$width));
				}
				else
				{
					$new_height = $size;
					$new_width=floor($new_height*($width/$height));
				}
			}
			
			//if you don't need to loss the image quality when the thumb width or height larger than the original sizes
			//then uncomment below code block, then it will be loaded with the original image size but not in the expected size
			/*if($new_width>$width || $new_height>$height)
			{
				$new_width = $width;
				$new_height = $height;
			}*/
			
			//create a temporary image
			$tmp_img=$this->create_temp_image($new_width, $new_height);
			
			// copy and resize old image into new image
			imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
			
			$this->export_temp_image($info["extension"], $tmp_img, $quality);
		}
		else
		{
			$size=intval($size);
			
			$img = imagecreatetruecolor($size, $size);
			imagesavealpha($img, true);
			$color = imagecolorallocatealpha($img, 0, 0, 0, 127);
			imagefill($img, 0, 0, $color);
			
			$this->export_temp_image("png", $img, $quality);
		}
	}
	
	/**
	 * @param string extension - image file's extension
	 * @param string tmp_img - Temporary image which was created using GD libarary
	 * @param string quality - quality for the rendering image as a percentage
	 */
	function export_temp_image($extension, $tmp_img, $quality)
	{
		$extension=strtolower($extension) ;
		
		// save thumbnail into a file
		if($extension == "jpg" || $extension == "jpeg")
		{
			@header("Content-Type: image/jpeg");
			imagejpeg($tmp_img, NULL, $quality);
		}
		else if($extension == "gif")
		{
			@header("Content-Type: image/gif");
			imagegif($tmp_img);
		}
		else if($extension == "png")
		{
			$quality = ($quality/100)*9;
			$quality = intval($quality);
			
			@header("Content-Type: image/png");
			imagepng($tmp_img, NULL, $quality);
		}
		imagedestroy($tmp_img);
	}
	
	/**
	 * @param string width - Width for the temporary image
	 * @param string height - Height for the temporary image
	 */
	function create_temp_image($width, $height)
	{
		// create a new temporary image
		$tmp_img = imagecreatetruecolor($width, $height);
		
		//making a transparent background for image
		imagealphablending($tmp_img, false);
		$colorTransparent = imagecolorallocatealpha($tmp_img, 0, 0, 0, 127);
		imagefill($tmp_img, 0, 0, $colorTransparent);
		imagesavealpha($tmp_img, true);
		
		return $tmp_img;
	}
	
	/**
	 * @param string extension - Source image's extension
	 * @param string path_to_image - Path for of the source image
	 */
	function get_image_width_height($extension, $path_to_image)
	{
		$extension=strtolower($extension) ;
		
		// load image and get image size
		if($extension == "jpg" || $extension == "jpeg")
		{
			$img = imagecreatefromjpeg($path_to_image);
		}
		else if($extension == "gif")
		{
			$img = imagecreatefromgif($path_to_image);
		}
		else if( $extension == "png")
		{
			$img = imagecreatefrompng($path_to_image);
		}
		
		$width = imagesx($img);
		$height= imagesy($img);
		
		return array($width, $height, $img);
	}
	
	/**
	 * @param string path_to_image - Path for the source image
	 */
	function is_valid_image($path_to_image)
	{
		//assume this is an invalid image
		$valid = false;
		
		if(@file_exists($path_to_image) && is_file($path_to_image))
		{
			try{
				$image_size = getimagesize($path_to_image);
				
				if(isset($image_size[2]) && in_array($image_size[2], array(IMAGETYPE_GIF , IMAGETYPE_JPEG ,IMAGETYPE_PNG , IMAGETYPE_BMP)))
				{
					$valid = true;
				}
			}
			catch(Exception $e)
			{
				
			}
		}
		
		return $valid;
	}
}
?>

You can download the full source code in a zipped file using below link.

Download Source Code

 

You may also like...

2 Responses

  1. jaquie says:

    Hello PNG file doesnt works 🙁 everything is ok but not PNG do you have an idea ?

    Thanks a lot

    • chamil512 says:

      Hi Jaquie,

      PNG files also working fine in script. If you can send me the code block of yours, then I can check for the issue.

Leave a Reply

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