简体   繁体   中英

Image resize and keep ratio bug

I found and modified a GD image resize and keep ratio script but it's not working as it should.

For example I want to resize a picture to MAXIMUM 200w x 200h keeping ratio. The picture I want to resize is 518w x 691h and the script should resize it to 150w x 200h to keep the aspect ratio but instead it resize it to 200w x 226h. What is the problem?

function resize_image($source_image, $name, $new_width, $new_height, $destination)
{
    list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image);

    switch($source_image_type)
    {
        case IMAGETYPE_GIF:
            $source_gd_image = imagecreatefromgif($source_image);
            break;
        case IMAGETYPE_JPEG:
            $source_gd_image = imagecreatefromjpeg($source_image);
            break;
        case IMAGETYPE_PNG:
            $source_gd_image = imagecreatefrompng($source_image);
            break;
    }

    $source_aspect_ratio = $source_image_width / $source_image_height;
    $thumbnail_aspect_ratio = $new_width / new_height;

    if($source_image_width <= $new_width && $source_image_height <= new_height)
    {
        $thumbnail_image_width = $source_image_width;
        $thumbnail_image_height = $source_image_height;
    }
    elseif ($thumbnail_aspect_ratio > $source_aspect_ratio)
    {
        $thumbnail_image_width = (int)(new_height * $source_aspect_ratio);
        $thumbnail_image_height = new_height;
    }
    else
    {
        $thumbnail_image_width = $new_width;
        $thumbnail_image_height = (int)($new_width / $source_aspect_ratio);
    }

    $thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);


    imagealphablending($thumbnail_gd_image, false);
    imagesavealpha($thumbnail_gd_image, true);


    imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);


    $destination = $destination.$name;

    switch($source_image_type)
    {
        case IMAGETYPE_GIF:
            imagegif($thumbnail_gd_image, $destination);
            break;
        case IMAGETYPE_JPEG:
            imagejpeg($thumbnail_gd_image, $destination, 100);
            break;
        case IMAGETYPE_PNG:
            imagepng($thumbnail_gd_image, $destination, 9);
            break;
    }


    imagedestroy($source_gd_image);
    imagedestroy($thumbnail_gd_image);
}

This section:

elseif ($thumbnail_aspect_ratio > $source_aspect_ratio)

should never execute, since you want to keep the aspect ratios the same. To determine the new width / height, try something like this:

if($width > $MAX_SIZE || $height > $MAX_SIZE) {
    $aspect = $width / $height;
    if($width > $height) {
        $width = $MAX_SIZE;
        $height = intval($MAX_SIZE / $aspect);
    } else {
        $height = $MAX_SIZE;
        $width = intval($MAX_SIZE * $aspect);
    }
}

Update

All this code is doing is attempting to determine a new width / height based on a restriction $MAX_SIZE , while keeping the aspect ratio the same. It's not going to be perfect because floating point arithemetic is rarely ever so (especially since in this case you can't have 'fractional' pixels, which is why the calculations above use intval ). Consider if, for example, before this code is ran $width , $height and $MAX_SIZE are set as follows:

$MAX_SIZE = 100;
$width = 1920;
$height = 1080;

The original aspect ratio is 1.77777777.... After running the snippet above, the width / height will be set to 100 x 56, which is an aspect ratio of 1.7857. Moving the output width/height either up or down by a pixel will not ever get you the exact input aspect ratio, unless you allow pixel values with fractional components.

However you're uploading the file and determining the input file's height / width shouldn't matter, the snippet above is only supposed to get you the resized dimensions as close as possible to the input aspect ratio.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM