Scale images to FIT/FILL bounding box in PHP using GD

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:

Image FIT/FILL example using PHP GD

Here is an example to give the idea how it works in two different modes

Fit mode

In fit mode it scales image to FIT image into bounding BOX leaving free space on the edges.


 

Fill mode

In FILL mod it scales image proportionally to fill entire bounding box with image, so no white space is left on the borders.


 

Like the pictures, ehh? :)

Source code

Examples below are generated in real time using code below, feel free to use it and improve.

<?
// Input parametres check
$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);
}
Did you find this post useful? Support the the author ($10)
My Google Profile+

17 comments

  1. Thanks for your code.

    Asking for permission to use it on my project in VB 🙂

    Enum ResizeMethod
    Fit
    Fill
    End Enum

    Function Resize(ByVal source As Size, ByVal destination As Size, ByVal method As ResizeMethod) As Rectangle
    Dim resized As RectangleF
    resized.Width = destination.Width
    resized.Height = destination.Width * source.Height / source.Width
    resized.X = 0
    resized.Y = (destination.Height – resized.Height) / 2
    If IIf(method = ResizeMethod.Fill, resized.Height destination.Height) Then
    resized.Width = destination.Height * source.Width / source.Height
    resized.Height = destination.Height
    resized.X = (destination.Width – resized.Width) / 2
    resized.Y = 0
    End If
    Return Rectangle.Round(resized)
    End Function

  2. 874841 850960I agree with most of your points, but a couple of require to be discussed further, I will hold a small talk with my partners and perhaps I will look for you some suggestion soon. 362393

  3. 792653 671451This post is dedicated to all people who know what is billiard table; to all people who do not know what is pool table; to all people who want to know what is billiards; 392901

  4. 968706 567200An interesting discussion is worth comment. I think that you should write more on this topic, it might not be a taboo subject but generally people are not enough to speak on such topics. To the next. Cheers 876863

  5. this is great solution for real estate websites, as different branches within the same company use different cameras hence the sizes are all over the place

  6. Hi, thank you for your code, will this work if i change source image to array(), like $src = array();
    I’m trying to ‘fit’ all thumbnails at once, and merge them into sprite at once. My sprite generator works but thumbnails are different sizez,and aligned to center. Is using python is better for generatin about 40 thumbnails at once? Sorry for my poor English

Leave a Reply

Your email address will not be published.