在 PHP GD 中:如何将图像缩放到特定宽度,同时保持其比例。然后从底部裁剪高度

In PHP GD: How to scale image to certain width, while maintaining its proportions. Then crop the height from the bottom

澄清一下,我希望模仿 HTML/CSS 中发生的以下行为。

<div style="width: 260px; height: 174px">
  <img src="path/img.png" style="width: 100%; overflow: hidden">  
</div>

这导致宽度始终是我的首选宽度,同时仍保持其比例。然后它看起来好像高度的底部被切断了,因为溢出被​​设置为隐藏。我想在使用 PHP GD 库生成图像时模仿这种行为。如果有明显的解决方案,我会提前道歉,但这是我尝试了太久而无济于事的方法。

$image = imagecreatefromstring(file_get_contents($uploadfile));
$filename = $uploaddir . '/thumb.png';

$thumb_width = 260;
$thumb_height = 174;

$width = imagesx($image);
$height = imagesy($image);

$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;

if ( $original_aspect >= $thumb_aspect )
{
  $new_height = $thumb_height;
  $new_width = $width / ($height / $thumb_height);
}
else
{
  $new_width = $thumb_width;
  $new_height = $height / ($width / $thumb_width);
}

$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );

imagecopyresampled($thumb, $image,
               0, 0,
               0, -$thumb_height,
               $new_width, $new_height,
               $width, $height);
imagepng($thumb, $filename, 5);

我将你的问题解读为:缩略图的宽度应始终为 260 像素(即使原始宽度小于 260 像素);高度不得超过 174px;但根据纵横比,它可能会更少。
让我们首先将目标宽度和最大高度设置为常量而不是变量。

define('THUMB_WIDTH', 260);
define('THUMB_MAX_HEIGHT', 174);

宽度你已经知道了,不用计算再赋给$new_height,就是THUMB_WIDTH.
但是你需要知道缩放因子,它是 THUMB_WIDTH / imagesx($image)(快速测试:图像宽度是 520 -> 缩放因子=0.5,似乎没问题)。
现在你计算给定比例因子的 $height,$height=imagesy($image)*scaling=>$height=imagesy($image)*THUMB_WIDTH/imagesx($image).
但这可能太大了。你想要更小的,THUMB_MAX_HEIGHT 或 $height =>

$thumb_height = min(
    THUMB_MAX_HEIGHT,
    $height
);

然后为图像创建资源 THUMB_WIDTH x $height px
并对完整图像重新采样,让 gd 处理裁剪。

所以完整的脚本应该是(没有错误处理并且完全未经测试)

<?php
define('THUMB_WIDTH', 260);
define('THUMB_MAX_HEIGHT', 174);

$image = imagecreatefromstring(file_get_contents($uploadfile));

$height = (int)ceil(imagesy($image) * THUMB_WIDTH / imagesx($image)); // (THUMB_WIDTH / imagesx($image)) being the scaling factor
$thumb_height = min(
    THUMB_MAX_HEIGHT,
    $height 
);

$thumb = imagecreatetruecolor( THUMB_WIDTH, $thumb_height);

imagecopyresampled(
    $thumb, $image,
    0, 0, // dest
    0, 0, // src
    THUMB_WIDTH, $height, // dest width/height - just draw the complete image, let gd handle the cropping
    imagesx($image), imagesy($image) // src width/height
);
imagepng($thumb);