在 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);
澄清一下,我希望模仿 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);