在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);

我把你的问题理解为:缩略图的宽度应始终为260px(即使原始缩略图的宽度<260px);高度最大为174px;但根据长宽比,它可能会更小
让我们先将目标宽度和最大高度设为常数,而不是变量。

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

您已经知道宽度,无需计算并将其分配给$new_height,它只是THUMB_width
但您需要知道缩放因子,即THUMB_WIDTH / imagesx($image)(快速测试:图像宽度为520->缩放因子=0.5,似乎可以)
现在,在给定缩放因子$height=imagesy($image)*scaling=>$height=imagesy($image)*THUMB_WIDTH/imagesx($image)的情况下计算$height
但这可能太大了。您想要更小的,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);