使用PHP缩放图像并保持纵横比

Ste*_*e_M 17 php image scale

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

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

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

编辑:我不需要整个代码或任何东西,只是推动正确的方向将是太棒了.

Flo*_*ima 19

实际上,接受的解决方案并不是正确的解决方案.原因很简单:存在源图像与目标图像的比率不同的情况.任何计算都应反映出这种差异.

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

$ratio_orig = $width_orig/$height_orig;

if ($width/$height > $ratio_orig) {
   $width = $height*$ratio_orig;
} else {
   $height = $width/$ratio_orig;
}
Run Code Online (Sandbox Code Playgroud)

完整的示例可以在这里找到: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;
    }
Run Code Online (Sandbox Code Playgroud)

高度= 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;
    }
Run Code Online (Sandbox Code Playgroud)

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

两者都失败了

我们根据PHP.net提出的解决方案进行数学计算:width = 160 height = 160 /(1630/2400)= 160/0.6791666666666667 = 235.5828220858896(else子句).160 x 236(圆形)是正确答案.


Phi*_*oss 13

我已经为我做过的另一个项目编写过这样的代码.我在下面复制了它,可能需要一些修补!(它确实需要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
Run Code Online (Sandbox Code Playgroud)

它会将图像向下或向上缩小到最大宽度或高度

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你肯定是说 `$thumb_h = $old_y*($new_width/$old_x);` 和 `$thumb_w = $old_x*($new_height/$old_y);` 当源图像不是正方形时,这将始终调整为最大可能的缩略图以 `$new_height` 作为最大高度,`$new width` 作为最大宽度 (2认同)

use*_*327 6

保持纵横比的公式是错误的。应该是:原始高度/原始宽度x新宽度=新高度

function createThumbnail($imageName,$newWidth,$newHeight,$uploadDir,$moveToDir)
{
    $path = $uploadDir . '/' . $imageName;

    $mime = getimagesize($path);

    if($mime['mime']=='image/png'){ $src_img = imagecreatefrompng($path); }
    if($mime['mime']=='image/jpg'){ $src_img = imagecreatefromjpeg($path); }
    if($mime['mime']=='image/jpeg'){ $src_img = imagecreatefromjpeg($path); }
    if($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    =   $newWidth;
        $thumb_h    =   $old_y/$old_x*$newWidth;
    }

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

    if($old_x == $old_y)
    {
        $thumb_w    =   $newWidth;
        $thumb_h    =   $newHeight;
    }

    $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 . $imageName;

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

    imagedestroy($dst_img);
    imagedestroy($src_img);
    return $result;
}
Run Code Online (Sandbox Code Playgroud)

  • 只是,它不保持纵横比。如果我想将 300x300 图像调整为 500x200,它将创建一个 500x200。 (2认同)