Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize/crop/pad a picture to a fixed size

Tags:

php

resize

crop

I need to resize a picture to a fixed size. But it has to keep the factors between the width and height.

Say I want to resize a picture from 238 (w) X 182 (h) to 210 / 150

What I do now is:

Original width / target width = 1.333333
Original Height / target Height = 1.213333

Now I take the smallest factor.

Now I always have the right width since 238 / 1.333333 = 210. But the height is still 160.

How do I get the height down to 160 without ruining the pic?

Do I need to crop? If so how?

like image 423
sanders Avatar asked Apr 14 '09 11:04

sanders


People also ask

How do I crop a picture without losing it size?

One way to do this is to use a program like Photoshop. With Photoshop, you can resize an image without losing quality by using the "Image Size" dialog box. In the "Image Size" dialog box, you can change the width and height of the image. You can also change the resolution.

How do I crop a picture to a custom ratio?

Crop Image to an Aspect RatioClick Upload an image and select the image you want to crop. Under step 2, click the Fixed Aspect Ratio button, then enter that ratio, such as 5 and 2, and click Change. Drag a rectangle over the image to select the area you want. Move the selection as needed, then click Crop.


2 Answers

This solution is basically the same as Can Berk Güder's, but after having spent some time writing and commenting, I felt like posting.

This function creates a thumbnail that is exactly as big as the size you give it. The image is resized to best fit the size of the thumbnail. If it does not fit exactly in both directions, it's centered in the thumnail. Extensive comments explain the goings-on.

function thumbnail_box($img, $box_w, $box_h) {
    //create the image, of the required size
    $new = imagecreatetruecolor($box_w, $box_h);
    if($new === false) {
        //creation failed -- probably not enough memory
        return null;
    }


    //Fill the image with a light grey color
    //(this will be visible in the padding around the image,
    //if the aspect ratios of the image and the thumbnail do not match)
    //Replace this with any color you want, or comment it out for black.
    //I used grey for testing =)
    $fill = imagecolorallocate($new, 200, 200, 205);
    imagefill($new, 0, 0, $fill);

    //compute resize ratio
    $hratio = $box_h / imagesy($img);
    $wratio = $box_w / imagesx($img);
    $ratio = min($hratio, $wratio);

    //if the source is smaller than the thumbnail size, 
    //don't resize -- add a margin instead
    //(that is, dont magnify images)
    if($ratio > 1.0)
        $ratio = 1.0;

    //compute sizes
    $sy = floor(imagesy($img) * $ratio);
    $sx = floor(imagesx($img) * $ratio);

    //compute margins
    //Using these margins centers the image in the thumbnail.
    //If you always want the image to the top left, 
    //set both of these to 0
    $m_y = floor(($box_h - $sy) / 2);
    $m_x = floor(($box_w - $sx) / 2);

    //Copy the image data, and resample
    //
    //If you want a fast and ugly thumbnail,
    //replace imagecopyresampled with imagecopyresized
    if(!imagecopyresampled($new, $img,
        $m_x, $m_y, //dest x, y (margins)
        0, 0, //src x, y (0,0 means top left)
        $sx, $sy,//dest w, h (resample to this size (computed above)
        imagesx($img), imagesy($img)) //src w, h (the full size of the original)
    ) {
        //copy failed
        imagedestroy($new);
        return null;
    }
    //copy successful
    return $new;
}

Example usage:

$i = imagecreatefromjpeg("img.jpg");
$thumb = thumbnail_box($i, 210, 150);
imagedestroy($i);

if(is_null($thumb)) {
    /* image creation or copying failed */
    header('HTTP/1.1 500 Internal Server Error');
    exit();
}
header('Content-Type: image/jpeg');
imagejpeg($thumb);
like image 177
gnud Avatar answered Oct 04 '22 06:10

gnud


This doesn't crop the picture, but leaves space around the new image if necessary, which I think is a better approach (than cropping) when creating thumbnails.

$w = 210;
$h = 150;

$orig_w = imagesx($original);
$orig_h = imagesy($original);

$w_ratio = $orig_w / $w;
$h_ratio = $orig_h / $h;

$ratio = $w_ratio > $h_ratio ? $w_ratio : $h_ratio;

$dst_w = $orig_w / $ratio;
$dst_h = $orig_h / $ratio;
$dst_x = ($w - $dst_w) / 2;
$dst_y = ($h - $dst_h) / 2;

$thumbnail = imagecreatetruecolor($w, $h);

imagecopyresampled($thumbnail, $original, $dst_x, $dst_y,
                   0, 0, $dst_w, $dst_h, $orig_w, $orig_h);
like image 22
Can Berk Güder Avatar answered Oct 04 '22 08:10

Can Berk Güder