PHP/GD:如何处理 jpg 透明度?
Posted
技术标签:
【中文标题】PHP/GD:如何处理 jpg 透明度?【英文标题】:PHP/GD: How to handle jpg transparency? 【发布时间】:2019-01-04 19:22:49 【问题描述】:JPG 不支持透明度。
但是,您可以从例如 GIMP 导出具有透明区域的图像。在这种情况下,透明区域将在您的浏览器、Windows 资源管理器或其他软件中显示为黑色或白色。
我经常收到需要处理并以几种较小格式提供的此类文件。我使用 GD 库通过一些 php 脚本来做到这一点。问题是无法预测这些区域在处理后的版本中会变成黑色还是白色。即使是白色背景也可以变成黑色。
所以我的问题是是否可以通过某种方式检测 GD 中的这个“透明”区域并为其分配特定颜色。
例如看这两张图片: http://www.bilbil.com/9156-thickbox_default/bus.jpg http://bilbil.com/img/p/9/1/5/6/9156.jpg
目前我使用此代码:
$srcfile = "9158.jpg";
$dir ="/test/";
list($width, $height, $imgtype, $attr) = @getimagesize( $dir.$srcfile );
$src = imagecreatefromjpeg($dir.$srcfile);
$newheight=$newwidth = 800;
$img = imagecreatetruecolor ( $newwidth , $newheight );
$white = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $white);
imagecopyresampled($img, $src, ($newwidth-$width)/2, ($newheight-$height)/2, 0, 0, $width, $height, $width, $height);
if(!imagejpeg($img, $dir.'test.jpg', 97))
echo("Error creating testimage");
【问题讨论】:
它们不会“显示为”黑色或白色,它们是黑色或白色。您可以编写一些东西,为边缘的所有#000000 或#FFFFFF 像素设置 alpha 通道,然后以实际支持透明度的格式保存,但随后您将遇到锯齿问题和 JPEG 伪像。解决方案是让人们以正确的格式而不是 JPEG 向您发送图像。 当我在 Windows 资源管理器中看到 jpg 的图像背景为黑色而在浏览器中为白色时,除了“显示为”之外,我无法描述它。 【参考方案1】:在几乎所有情况下,您都可以使用左上角的像素颜色作为透明颜色。
【讨论】:
【参考方案2】:你可以给ImageMagick一个机会。以下命令会将 .jpeg 文件转换为具有透明度的 .png。
convert bus.jpg \
-alpha set -fill none -fuzz 1% \
-bordercolor white -border 1 -draw 'color 0,0 floodfill' -shave 1x1 \
-bordercolor black -border 1 -draw 'color 0,0 floodfill' -shave 1x1 \
a.png
这是它的工作原理:
-
在整个图像周围添加白色边框
从左上角开始用透明填充白色(以及所有与其相似的颜色 1%)
移除图片周围的多余边框
在整个图像周围添加黑色边框
从左上角开始用透明填充黑色(以及所有与其相似的颜色 1%)
移除图片周围的多余边框
将结果图像写入文件
a.png
这是 PHP 的 sn-p:
<?php
function jpg_to_png($jpg, $png)
$templ = trim("
convert jpg \
-alpha set -fill none -fuzz 1% \
-bordercolor white -border 1 -draw 'color 0,0 floodfill' -shave 1x1 \
-bordercolor black -border 1 -draw 'color 0,0 floodfill' -shave 1x1 \
png
");
$cmd = strtr($templ, [
'jpg' => escapeshellarg($jpg),
'png' => escapeshellarg($png)
]);
exec($cmd, $stdout, $exitcode);
if ($exitcode)
throw new Error("Command failed with code $exitcode");
jpg_to_png('bus.jpg', 'a.png');
以下命令 (ref) 也可能对您的情况有所帮助:
convert bus.jpg -fuzz 1% -trim +repage a.jpg
它将从输入图像中删除所有“空白”。
【讨论】:
【参考方案3】:我不确定你在问什么。您是从具有透明度的非 JPG 图像开始并转换为 JPG 吗?或者你已经有JPG。
如果您从 PNG 或 TIFF 等透明图像开始,并希望转换为 JPG 并且始终具有黑色(或任何其他颜色)背景,那么在 Imagemagick 中,您可以执行以下操作:
convert image.png -background black -alpha background -alpha off image.jpg
或
convert image.png -background black -flatten image.jpg
将黑色替换为透明的任何其他颜色,例如白色。
如果您已经有一个带有某种颜色的 JPG 并且想要将其更改为黑色,那么请执行以下操作:
convert image.jpg -fuzz XX% -fill black -opaque somecolor image.jpg
其中 XX% 是您想要考虑的接近“somecolor”的百分比,您想要将“somecolor”和附近的颜色更改为黑色。
对不起,我不知道 GD。但我希望它具有类似的功能。或者您可以使用基于 Imagemagick 构建的 PHP Imagick。
【讨论】:
以上是关于PHP/GD:如何处理 jpg 透明度?的主要内容,如果未能解决你的问题,请参考以下文章