Quite often I was in need a function to scale an image to the size right to fit into bounding box.
For example, displaying images of real estate or product image in the shop site. Images can be different sizes, less or bigger of target size, portrait or landscape, etc..
I wrote little helper function in PHP that does that tasks using two modes: FIT and FILL. It uses standard PHP-GD extension.
Why did I re-invent the wheel?
Solution seems easy and should be widely deployed, however I haven't found a working one on the Internet. All my findings didn't do the job right and the way they work was not clear and I was not able to fix them.
My function accepts source image, destination image and operation (FIT or FILL). It scales image UP and DOWN and uses a very simple algorithm. See examples below:
Here is an example to give the idea how it works in two different modes
Like the pictures, ehh? :)
Examples below are generated in real time using code below, feel free to use it and improve.
$w = intval($_GET['width']);
$h = intval($_GET['height']);
$mode = $_GET['mode']=='fit'?'fit':'fill';
if ($w <= 1 || $w >= 1000) $w = 100;
if ($h <= 1 || $h >= 1000) $h = 100;
// Source image
$src = imagecreatefromjpeg('./sample.jpg');
// Destination image with white background
$dst = imagecreatetruecolor($w, $h);
imagefill($dst, 0, 0, imagecolorallocate($dst, 255, 255, 255));
// All Magic is here
scale_image($src, $dst, $mode);
// Output to the browser
Header('Content-Type: image/jpeg');
imagejpeg($dst);
function scale_image($src_image, $dst_image, $op = 'fit') {
$src_width = imagesx($src_image);
$src_height = imagesy($src_image);
$dst_width = imagesx($dst_image);
$dst_height = imagesy($dst_image);
// Try to match destination image by width
$new_width = $dst_width;
$new_height = round($new_width*($src_height/$src_width));
$new_x = 0;
$new_y = round(($dst_height-$new_height)/2);
// FILL and FIT mode are mutually exclusive
if ($op =='fill')
$next = $new_height < $dst_height; else $next = $new_height > $dst_height;
// If match by width failed and destination image does not fit, try by height
if ($next) {
$new_height = $dst_height;
$new_width = round($new_height*($src_width/$src_height));
$new_x = round(($dst_width - $new_width)/2);
$new_y = 0;
}
// Copy image on right place
imagecopyresampled($dst_image, $src_image , $new_x, $new_y, 0, 0, $new_width, $new_height, $src_width, $src_height);
}