Sir Code-A-lot
Sir Code-A-lot

Reputation: 153

Cropping a photo with PHP gets stretched

I'm trying to resize and crop a picture.

The picture can be landscape or portrait oriented but I want the thumbnail to be 250x250 and not stretched (crop the sides or the top/bottom but keep most of the image intact in the new size, cropped to square - kinda like wordpress's thumbnails).

This is my function, it's the right size but its stretching the pictures...

What am i doing wrong?

function make_thumb($src, $dest, $desired_width, $ext) {

    if ($ext == 'jpg' || $ext == 'jpeg') {
            $source_image = imagecreatefromjpeg($src);      
    }
    if ($ext == 'png') {
            $source_image = imagecreatefrompng($src);       
    }
    if ($ext == 'gif') {
            $source_image = imagecreatefromgif($src);       
    }   

    /* read the source image */
    $width = imagesx($source_image);
    $height = imagesy($source_image);

/* find the "desired height" of this thumbnail, relative to the desired width  */
    $desired_height = floor($height * ($desired_width / $width));
    $desired_height = 250;

    /* create a new, "virtual" image */
    $virtual_image = imagecreatetruecolor($desired_width, $desired_height);

    /* copy source image at a resized size */
    imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height);

    /* create the physical thumbnail image to its destination */

    if ($ext == 'jpg' || $ext == 'jpeg') {
            imagejpeg($virtual_image, $dest);       
    }
    if ($ext == 'png') {
            imagepng($virtual_image, $dest);        
    }
    if ($ext == 'gif') {
            imagegif($virtual_image, $dest);        
    }   
}

Thanks!

Upvotes: 0

Views: 660

Answers (1)

RiggsFolly
RiggsFolly

Reputation: 94642

Think about what you are saying for a second.

If you change the width of an image and do not change the height in exactly the same proportion as you have the width, the image is always going to get distorted.

You have the code to do it properly, without distortion, although I have not actually tested the calc is correct and then you override that calculation with the arbitrary height of 250. Hence you get a distortion.

Comment out this line and it will probably stop the distortion

$desired_height = 250;

So if you know you always want an image that is 250 height, change the calulation to calulate the proportionate new width rather than passing it in as a parameter.

function make_thumb($src, $dest, $desired_height = 250, $ext) {

    if ($ext == 'jpg' || $ext == 'jpeg') { $source_image = imagecreatefromjpeg($src);  }
    if ($ext == 'png') { $source_image = imagecreatefrompng($src); }
    if ($ext == 'gif') { $source_image = imagecreatefromgif($src); }   

    /* read the source image */
    $width = imagesx($source_image);
    $height = imagesy($source_image);

    /* calc the new width */
    $desired_width = floor($width * ($desired_height / $height));

    /* create a new, "virtual" image */
    $virtual_image = imagecreatetruecolor($desired_width, $desired_height);

    /* copy source image at a resized size */
    imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height);

    /* create the physical thumbnail image to its destination */

    if ($ext == 'jpg' || $ext == 'jpeg') { imagejpeg($virtual_image, $dest); }
    if ($ext == 'png') { imagepng($virtual_image, $dest); }
    if ($ext == 'gif') { imagegif($virtual_image, $dest); }   
}

Of course the width will vary a bit depending on the actual size of the original image. But you have to let that happen if you want to stop the distortion.

Upvotes: 1

Related Questions