使用 PHP 缩放图像并保持宽高比

2022-08-30 17:02:48

基本上,我想上传一个图像(我已经排序了)并将其缩小到某些约束,例如最大宽度和高度,但保持原始图像的宽高比。

我没有在服务器上安装Imagick - 否则这很容易。

任何帮助都一如既往地受到赞赏。谢谢。

编辑:我不需要整个代码或任何东西,只要朝着正确的方向推动就会很棒。


答案 1

实际上,公认的解决方案它不是正确的解决方案。原因很简单:在某些情况下,源图像的比例与目标图像的比例会有所不同。任何计算都应反映这种差异。

请注意 PHP.net 网站上给出的示例中的相关行:

$ratio_orig = $width_orig/$height_orig;

if ($width/$height > $ratio_orig) {
   $width = $height*$ratio_orig;
} else {
   $height = $width/$ratio_orig;
}

完整的例子可以在这里找到:http://php.net/manual/en/function.imagecopyresampled.php

对于遭受相同问题的类似问题(以不同方式表述的相同问题),还有其他答案(带有示例)。

例:

假设我们有一个1630 x 2400像素的图像,我们希望自动调整大小,使宽高比保持为160 x 240。让我们用公认的解决方案做一些数学运算:

if($old_x < $old_y) 
    {
        $thumb_w    =   $old_x*($new_width/$old_y);
        $thumb_h    =   $new_height;
    }

高度 = 240 宽度 = 1630 * ( 160/2400 ) = 1630 * 0.0666666666666667 = 108.6666666666667 108.6 x 240 这不是正确的解决方案。

建议的下一个解决方案如下:

if($old_x < $old_y)
    {
        $thumb_w    =   $old_x/$old_y*$newHeight;
        $thumb_h    =   $newHeight;
    }

高度 = 240;宽度 = 1630 / 2400 * 240 = 163 它更好(因为它保持了纵横比),但它超过了最大可接受的宽度。

两者都失败了。

我们根据 PHP.net 提出的解决方案进行数学运算:宽度 = 160 高度 = 160/(1630 / 2400) = 160/0.6791666666666667 = 235.5828220858896(else 子句)。160 x 236(四舍五入)是正确的答案。


答案 2

我为我做过的另一个项目写了一段这样的代码。我已经在下面复制了它,可能需要一些修补!(它确实需要GD库)

这些是它需要的参数:

$image_name - Name of the image which is uploaded
$new_width - Width of the resized photo (maximum)
$new_height - Height of the resized photo (maximum)
$uploadDir - Directory of the original image
$moveToDir - Directory to save the resized image

它将图像缩小或放大到最大宽度或高度

function createThumbnail($image_name,$new_width,$new_height,$uploadDir,$moveToDir)
{
    $path = $uploadDir . '/' . $image_name;

    $mime = getimagesize($path);

    if($mime['mime']=='image/png') { 
        $src_img = imagecreatefrompng($path);
    }
    if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
        $src_img = imagecreatefromjpeg($path);
    }   

    $old_x          =   imageSX($src_img);
    $old_y          =   imageSY($src_img);

    if($old_x > $old_y) 
    {
        $thumb_w    =   $new_width;
        $thumb_h    =   $old_y*($new_height/$old_x);
    }

    if($old_x < $old_y) 
    {
        $thumb_w    =   $old_x*($new_width/$old_y);
        $thumb_h    =   $new_height;
    }

    if($old_x == $old_y) 
    {
        $thumb_w    =   $new_width;
        $thumb_h    =   $new_height;
    }

    $dst_img        =   ImageCreateTrueColor($thumb_w,$thumb_h);

    imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 


    // New save location
    $new_thumb_loc = $moveToDir . $image_name;

    if($mime['mime']=='image/png') {
        $result = imagepng($dst_img,$new_thumb_loc,8);
    }
    if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
        $result = imagejpeg($dst_img,$new_thumb_loc,80);
    }

    imagedestroy($dst_img); 
    imagedestroy($src_img);

    return $result;
}

推荐