Resize panoramic image to fixed size

2019-07-19 14:15发布

问题:

I want to resize the images to fixed width and height (i.e. 150px). However, theres a problem, if there is lots of difference in height and width of original photo (for example, panoramic photo), the resized thumbnail looks bad. Is there any any smart solution to resize the photos to a fixed width and height? For example, please have a look at this image:

Here's my code:

<?php
    $params = getimagesize($tempFile);
    $width = $params[0];
    $height = $params[1];

    $newwidth=150;
    $newheight= 150;
    $tmp=imagecreatetruecolor($newwidth,$newheight);

    imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
    imagejpeg($tmp,$img_name,80);

    imagedestroy($src);
    imagedestroy($tmp); 
?>

Is there any smart way to resize the images in smart way? Thanks.

回答1:

There's a smart solution, it's called Seam Carving, and if your server supports ImageMagick, you do it like this:

<?php
$im = new Imagick( 'image.jpg' );
$im->liquidRescaleImage( 600, 100, 3, 25 );
header( 'Content-Type: image/jpg' );
echo $im;
?>

Or alternatively, if it doesn't support, use exec() (carefully) in order to pass image as an argument to executable which can perform seam carving.

BTW it looks like twitpic just crop's the squared image extract. In one of my previous projects I used following code:

if ($image->width > $image->height){
    //crop image in proportions 4/3, then resize to 500x300 (or proportionally lower resolution), 
    //sharp it a little and decrease quality. 
    //I used one of the Yii framework extensions.
    $image->crop($image->width, $image->width/4*3)->resize(500, 300, Image::WIDTH)->sharpen(15)->quality(75);
}


回答2:

It looks like twitpic is finding out how long the short axis is, then takes a square centered on the original image with sides equal to the short axis length, then shrinking that down to 150x150.



回答3:

Not, resmaple, get only center 150x150 pixels.



回答4:

You will need to calculate the appropriate coordinates for the original area you want to copy:

imagecopyresampled($tmp,$src,0,0,[THIS VALUE],[THIS VALUE],$newwidth,$newheight, [THIS VALUE],[THIS VALUE]);

As of now, you take the area from 0,0 (x,y) to width,height (x,y) of the original area and try to cramp it into 150x150.

you will need to calculate which of width and height that is the "biggest" and crop that and make sure that the ratio is the same as your resulting image (in your case, ratio is 1.0 because of 150x150).

In your example, where width is 1050 and height is 317 pixels so you want a portion of the original image that is 317x317 (ratio 1.0), you need to:

subtract 317 from 1050 = 733; // this is the excessive area for both sides
divide by 2 =~ 366; // to get the excessive area for one side

Now, use first x coordinate 366, to start 366 pixels from the left. Use second x coordinate 1050 - 366 start 366 pixels from the right.

So your example should be (just guessing here):

imagecopyresampled($tmp,$src,0,0,366,0,$newwidth,$newheight, $width - 366, 0);

You will of course need some logic in order to calculate this correctly for any other size.



标签: php resize