imagecopyresampled() 导致分割颜色背景 imagefill()

Posted

技术标签:

【中文标题】imagecopyresampled() 导致分割颜色背景 imagefill()【英文标题】:imagecopyresampled() results in split color background imagefill() 【发布时间】:2015-05-19 18:58:00 【问题描述】:

我有一个脚本,它拍摄一张图片,并在重新采样时将短尺寸(宽度或高度)居中放置在方形彩色背景上。 这适用于具有较长宽度的图像,但由于某种原因,任何具有较长高度的图像结果都是分割背景填充 - 左侧是正确的颜色,但右侧是默认的黑色。如果我使用 x 轴偏移量,则背景填充只会向右延伸到图像位置。

计算的值与垂直图像的预期值一样,所以我无法弄清楚这里发生了什么。请注意,“imagecopy()”会产生完全相同的行为。

原始图像为 155 x 400 像素 为方形纵横比调整源尺寸 = 400 x 400 像素 生成的缩略图为 250 x 250 像素

这是一个示例的静态值代码:

$thumb = imagecreatetruecolor(250, 250);

imagecopyresampled($thumb, $source, 77, 0, 0, 0, 250, 250, 400, 400);

$blue = imagecolorallocate($thumb, 0xDE, 0xE6, 0xF9);
imagefill($thumb, 0, 0, $blue);

使用相同的图像旋转 90 度(400 x 155 像素),使其水平更长 应用完整的背景填充:

imagecopyresampled($thumb, $source, 0, 77, 0, 0, 250, 250, 400, 400);

对于垂直图像,我的坐标值 (77, 0) 将图像放在 imagecreatetruecolor() 画布上,正好在我想要的位置居中,但更改任何其他 imagecopyresampled() 值会拉伸或挤压重新采样的图像或裁剪它.

我是否忽略了一些简单的事情?在此处查看屏幕截图: http://i.stack.imgur.com/5CxHU.jpg(垂直问题)和 http://i.stack.imgur.com/wvhzP.jpg(横向OK)

【问题讨论】:

0,77 和 250,250 表示“在水平 0 和垂直 77 处,开始绘制 250x250 的图像”。例如0,77 -> 250,327,因此您正在绘制目标图像的底部,因为您在图片顶部“浪费”了 77 个像素。 我在上面进行了编辑以澄清水平图像 (400 x 155 像素) 可以工作 (0,77),它是导致 imagefill() 问题的垂直图像 (155 x 400 像素)。我还附上了屏幕截图的链接。 这会正确应用背景填充:$thumb = imagecreatetruecolor(250, 327); ...但是在底部留下了多余的 77 像素,然后我需要使用 imagecopy() 或 imagecrop() 进行裁剪...只是希望我能一步一步弄清楚如何获得它。 【参考方案1】:

这个垂直问题一定与 php 的重采样/图像填充算法 (?) 有关,但这里有一个解决方法,现在可以将我的所有垂直图像居中在我的方形画布中:

1) 您需要先填充您的图像占位符,以便背景填充将延伸到重新采样图像的右边缘,方法是使用您的 x 轴偏移量扩展缩略图高度(听起来很奇怪,但它有效)......我们会稍后将其删除:

$thadj_height = $th_height + $th_x;
$thumb = imagecreatetruecolor($th_width, $thadj_height);

2) 像往常一样使用背景填充重新采样(请注意,填充是在重新采样语句之后应用的,奇怪但只是这样工作)...请记住,$thumb 的高度大于 $th_width, $th_height 将占据的高度:

imagecopyresampled($thumb, $source, $th_x, $th_y, 0, 0, $th_width, $th_height, $src_width, $src_height);
imagefill($thumb, 0, 0, $bgcolor);

3) 暂时保存图像输出,以便接下来可以对其应用新功能 - 将质量设置为无损,因为我们将重复使用它:

imagejpeg($thumb, "resampled/output_temp.jpg", 100);
imagedestroy($thumb);

4) 检索临时文件并获取新维度(覆盖之前的变量):

$file = "resampled/output_temp.jpg";
$image = file_get_contents($file);
$source = imagecreatefromstring($image);
list($src_width, $src_height) = getimagesize($file);

5) 创建一个新的图像占位符,在我的情况下最初是方形的:

$thumb = imagecreatetruecolor($th_width, $th_height);

6) 现在将临时填充的缩略图复制到方形占位符中,这将导致裁剪掉填充:

imagecopy($thumb, $source, 0, 0, 0, 0, $src_width, $src_height);

header('Content-Type: image/jpeg');
echo imagejpeg($thumb);
imagedestroy($thumb);

同样,将我的水平图像居中在方形画布上时,这些都不是必需的,但这是一种解决方法,可以消除分割填充背景。

【讨论】:

以上是关于imagecopyresampled() 导致分割颜色背景 imagefill()的主要内容,如果未能解决你的问题,请参考以下文章

PHP - ImageCopyResampled 的问题

imagecopyresampled 裁剪 黑条

PHP imagecopyresampled + 如何获得最佳结果

GD库imagecopyresampled()方法详解~

PHP GD imagecopyresampled() 并将其水平翻转

php imagecopyresampled - 保存后图像为空(全黑)