I made this PHP class that loads any image you specify and resizes it to any size you want.
Features
If the size you specify is greater than the original, it will not stretch the image but use padding instead. Or if the size you requested is not the original aspect ratio, it will not distort the image but use padding to match the requested size.
You can specify what color you want the padding to be, default is white. It preserves transparency in .png files. You can specify what output you want to use (.jpeg/.gif/.png) but it defaults to the original file type.
Primary Purpose
The main reason I wanted to make this class was so that I could upload 1 large file and use it throughout the site. So I would not need to create several copies of the same image in different sizes (large, thumbnail, etc.)
In theory I wanted to be able to upload the largest version of the image I have, then still be able to load a page with 50 small thumbnails relatively fast because the large images are being shrunk before they are loaded.
Problem
It does work, however, when loading a very large image as a thumbnail, it still seems to take about the same amount of time as if it were not shrinking. Only instead of waiting for it to actually download you are waiting for the image to be processed and resampled before you can begin download. This delay only happens when processing large images. The one I used was 5MB.
Code
class ImageSrv
{
private $image;
private $original_width;
private $original_height;
private $original_type;
// default colors for background and padding
private $r = 255;
private $g = 255;
private $b = 255;
function load($image_file)
{
$this->image = $this->createImageFromFile($image_file);
}
function setBackground($r, $g, $b)
{
$this->r = (int) $r;
$this->g = (int) $g;
$this->b = (int) $b;
}
function createImageFromFile($image_file)
{
$image_info = getimagesize($image_file);
$this->original_width = $image_info[0];
$this->original_height = $image_info[1];
$this->original_type = $image_info[2];
if( $this->original_type == IMAGETYPE_JPEG )
{
return imagecreatefromjpeg($image_file);
}
else if( $this->original_type == IMAGETYPE_GIF )
{
return imagecreatefromgif($image_file);
}
else if( $this->original_type == IMAGETYPE_PNG )
{
/*
* create image and preserve transpancy
* this keeps png files from having a black backgroung
* when you don't resize them.
* pngs converted to jpgs still have a black background
* not sure how to make it a different color
*/
$im = imagecreatefrompng($image_file);
imagealphablending($im, false);
imagesavealpha($im, true);
return $im;
}
}
function setSize($width = NULL,$height = NULL)
{
if($width == NULL && $height == NULL)
{
return;
}
$ratio = $this->original_width / $this->original_height;
$new_ratio = $width / $height;
if($width == NULL)
{
$width = $height*$ratio;
if($width > $this->original_width)
{
$width = $this->original_width;
}
}
else if($height == NULL)
{
$height = $width/$ratio;
if($height > $this->original_height)
{
$height = $this->original_height;
}
}
// if width is greater than original width
// set to original width and pad the difference
if($width < $this->original_width)
{
$w = $width;
}
else
{
$w = $this->original_width;
}
// if height is greater than original height
// set to original height and pad the difference
if($height < $this->original_height)
{
$h = $height;
}
else
{
$h = $this->original_height;
}
// check if new deminsions are same aspect ratio
// if not, fix aspect ratio and pad the difference
if( $w / $h != $ratio )
{
if($width > $w && $height > $h)
{
//no scaling
}
else if($width > $w)
{
$w = $h*$ratio;
}
else if($height > $h)
{
$h = $w/$ratio;
}
else if($ratio < $new_ratio)
{
$w = $h*$ratio;
}
else
{
$h = $w/$ratio;
}
}
// resize image with correct aspect ratio and use padding to meet required size
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
imagesavealpha($image, true);
$transparent = imagecolorallocatealpha($image, $this->r, $this->g, $this->b, 127);
imagefill($image, 0, 0, $transparent);
imagecopyresampled($image, $this->image, ($width - $w) / 2 , ($height - $h) / 2, 0, 0, $w, $h, $this->original_width, $this->original_height);
$this->image = $image;
// reset original width and height to the new width and height
$this->original_width = $width;
$this->original_height = $height;
}
function output($type=NULL)
{
if($type == NULL)
{
$type = $this->original_type;
}
if( $type == IMAGETYPE_JPEG )
{
header('Content-Type: image/jpeg');
imagejpeg($this->image);
}
else if( $type == IMAGETYPE_GIF )
{
header('Content-Type: image/gif');
imagegif($this->image);
}
else if( $type == IMAGETYPE_PNG )
{
header('Content-Type: image/png');
imagepng($this->image);
}
}
}
Is there anything I can do to improve this performance?