【发布时间】:2018-01-18 20:39:25
【问题描述】:
我正在使用 PHP 生成动态图像,该图像是具有透明度的 PNG。
在此过程中,我在图像顶部添加了一个透明的 PNG 标志,同时保留了它的透明度。
当我使用 php imagepng($destination) 将最终产品输出为 PNG 时,我目前可以正常工作。
但是,由于它是 PNG,因此我的图像尺寸相当大,我需要将最终输出转换为 gif(以保持背景图像的透明度)。
这是我的代码:
$data = [
'name' => [
'x' => ($noBG ? 150 : 400),
'y' => ($noBG ? 700 : 920),
'size' => 40,
'angle' => 0,
'content' => $name,
],
'pin' => [
'x' => ($noBG ? 130 : 440),
'y' => ($noBG ? 475 : 700),
'size' => 75,
'angle' => 0,
'content' => implode(' ', str_split($pin)),
],
'denomination' => [
'x' => denominationPosition($denomination, $noBG),
'y' => ($noBG ? 150 : 375),
'size' => 70,
'angle' => 0,
'content' => $denomination,
],
'defaultText' => [
'x' => ($noBG ? 150 : 400),
'y' => ($noBG ? 780 : 980),
'size' => 30,
'angle' => 0,
'content' => 'It Doesn\'t Cost - It PAY$!',
],
'logo' => [
'x' => ($noBG ? 875 : 1200),
'y' => ($noBG ? 675 : 880),
],
];
// Are we using the template with or without a background?
if($noBG){
$style = 'assets/images/templateNoBG.png';
}else{
$style = 'assets/images/template.png';
}
// Did we pass a logo?
if ($logo) {
$src = imagecreatefrompng($logo);
}else{
$src= imagecreatefrompng($noLogo);
}
// Transparent sponsor logo
imagealphablending($src, false);
imagesavealpha($src, true);
// Define our source image (the background)
$destination = imagecreatefrompng($style);
// Colors
$textColor = imagecolorallocate($destination, 255, 255, 255);
$regularFont = 'assets/fonts/Bungee-Regular.otf';
// Transparent background
imagealphablending($destination, true);
imagesavealpha($destination, true);
// Name
imagettftext($destination, $data['name']['size'], $data['name']['angle'], $data['name']['x'], $data['name']['y'], $textColor, $regularFont, $data['name']['content']);
// Pin
imagettftext($destination, $data['pin']['size'], $data['pin']['angle'], $data['pin']['x'], $data['pin']['y'], $textColor, $regularFont, $data['pin']['content']);
// Denomination
imagettftext($destination, $data['denomination']['size'], $data['denomination']['angle'], $data['denomination']['x'], $data['denomination']['y'], $textColor, $regularFont, '$' . $data['denomination']['content']);
// Default Text
imagettftext($destination, $data['defaultText']['size'], $data['defaultText']['angle'], $data['defaultText']['x'], $data['defaultText']['y'], $textColor, $regularFont, $data['defaultText']['content']);
// Merge the logo and template together
imagecopy($destination, $src, $data['logo']['x'], $data['logo']['y'], 0, 0, $logoWidth, $logoHeight);
// Create our header to flush the image to browser
//header("Content-type: image/png");
header("Content-type: image/gif");
header("Cache-Control: no-store, no-cache");
/**
* Un-comment to ask to save file
* header('Content-Disposition: attachment; filename="DiningCard.png"');
*/
// Render image
//imagepng($destination); // Works
imagegif($destination);
// Cleanup
imagedestroy($destination);
/**
* Depending on the number of of numbers in the denomination,
* pass x coordinates to help keep it in position
*/
function denominationPosition($denomination, $noBG)
{
switch (strlen($denomination)) {
case 1:
return ($noBG ? 1150 : 950);
break;
case 2:
return ($noBG ? 1100: 1400);
break;
case 3:
return ($noBG ? 1050 : 1350);
break;
case 4:
return ($noBG ? 950 : 1290);
break;
}
}
我遇到的问题是,当我使用imagegif($destination) 时,背景图像正在失去透明度并且全部变形。
图像的背景应该是透明的,但您可以看到失真和缺少 Alpha 通道。
当通过imagepng() 输出为png 时,一切正常。
这是PNG版本:
我把它放在一个 bitbucket 存储库中,以防有人想查看代码 - 仅查看代码就很难解决此类问题。
https://bitbucket.org/sbbdev/cardgen/src
关于如何获得 gif 版本的任何想法?两者之间的大小差异对于开始工作至关重要。
【问题讨论】:
-
我没有时间尝试这个,但是尝试分配一个透明颜色作为加载背景图像后的第一件事,例如
$transp = imagecolorallocatealpha($destination,255,255,255,127); -
GIF 不是真彩色格式,也不支持 Alpha 通道透明度。当您要求 PHP 输出 GIF 时,它会将资源缩减为 8 位 (256) 调色板。由于您没有通过
imagecolortransparent专门设置透明颜色,因此没有透明度。 -
@timclutton - 想尝试一下答案吗?非常愿意为快速解决方案奖励赏金:)
-
@SBB 我几天前看过这个。您将不得不决定要妥协的地方:质量或尺寸。 PNG出来〜900KiB,而GIF〜300KiB。你的用例是什么?为什么缩小尺寸很重要?您可以运行服务器端优化器吗? (只需通过 tinypng.com 运行
templateNoBG.png即可将其从 1.02MiB 减少到 227KiB,而没有明显的质量损失。) -
@timclutton - 我的用例是这张图片将在每个用户自定义的电子邮件活动中发出。在进行一些测试时,当他的图像出现并加载到电子邮件中时,会有几秒钟的中继。 gif 版本几乎立即出现(当然基于我自己的速度)。在某种程度上,质量和尺寸都很重要。你知道 tinypng 对图像做了什么来减少我可以在我这边启用的图像吗?