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

时间:2015-12-27 01:26:22

标签: php gd php-gd

为了澄清,我希望模仿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);

1 个答案:

答案 0 :(得分:1)

我将您的问题读作:缩略图的宽度始终为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 =&gt; $height=imagesy($image)*THUMB_WIDTH/imagesx($image)计算$ height 但这可能太大了。你想要更小的东西,THUMB_MAX_HEIGHT或$ height =&gt;

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