PHP GD2:如何维护alpha通道透明度和正确的伽玛
-
26-09-2020 - |
题
<?php
$image = imagecreatefrompng($source_file);
$resized_image = imagecreatetruecolor($new_width, $new_height);
imagealphablending($resized_image, false);
imagesavealpha($resized_image, true);
imagegammacorrect($image, 2.2, 1.0);
imagecopyresampled($resized_image, $image, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height);
imagegammacorrect($resized_image, 1.0, 2.2);
imagepng($resized_image, $dest_file);
?>
.
任何人都知道如何调整图像的大小,采用伽玛校正技巧,同时保持原始图像的alpha通道透明度?
编辑
样本图像:
- 原始文件 - 具有alpha通道透明度的png
- 使用imagegammacorrect()函数调用的调整大小文件注释出
- 使用imagegammAcagorrect()函数调用的调整大小文件
您可以看到透明度很好,直到您尝试纠正伽玛。 (最简单的方法看透明度在下面工作是检查围绕图像包裹的段落标记,并添加背景:Black;通过Firebug或类似的风格属性。)
原始图片http://eders.hosting.emarketsoutoutouth.com/images /test-image.png 否伽玛修正http://ender.hosting.emarketsou .com /图像/测试 - 图像调整大小 - no-gamma.png 伽玛纠正 - 没有透明度http://eder.hosting.emarketsoutoutoul.com /images/test-image-resized.png
解决方案
这是一些工作的代码。基本上,它将alpha通道分开,使用伽玛正确调整图像的大小,调整alpha通道而没有伽玛正确,然后在alpha通道上拷贝到用gamma正确完成的调整大小图像。
我的猜测是imagegammarrect()函数有一个错误。也许伽玛仅适用于RGB,GD尝试对alpha通道进行相同的计算?颜色理论不是我的强项。
无论如何,这是代码。不幸的是,我找不到一个更好的方法来分开频道,而不是逐个循环像素。哦,好吧......
<?php
// Load image
$image = imagecreatefrompng('test-image.png');
// Create destination
$resized_image = imagecreatetruecolor(100, 100);
imagealphablending($resized_image, false); // Overwrite alpha
imagesavealpha($resized_image, true);
// Create a separate alpha channel
$alpha_image = imagecreatetruecolor(200, 200);
imagealphablending($alpha_image, false); // Overwrite alpha
imagesavealpha($alpha_image, true);
for ($x = 0; $x < 200; $x++) {
for ($y = 0; $y < 200; $y++) {
$alpha = (imagecolorat($image, $x, $y) >> 24) & 0xFF;
$color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
imagesetpixel($alpha_image, $x, $y, $color);
}
}
// Resize image to destination, using gamma correction
imagegammacorrect($image, 2.2, 1.0);
imagecopyresampled($resized_image, $image, 0, 0, 0, 0, 100, 100, 200, 200);
imagegammacorrect($resized_image, 1.0, 2.2);
// Resize alpha channel
$alpha_resized_image = imagecreatetruecolor(200, 200);
imagealphablending($alpha_resized_image, false);
imagesavealpha($alpha_resized_image, true);
imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, 100, 100, 200, 200);
// Copy alpha channel back to resized image
for ($x = 0; $x < 100; $x++) {
for ($y = 0; $y < 100; $y++) {
$alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
$rgb = imagecolorat($resized_image, $x, $y);
$r = ($rgb >> 16 ) & 0xFF;
$g = ($rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$color = imagecolorallocatealpha($resized_image, $r, $g, $b, $alpha);
imagesetpixel($resized_image, $x, $y, $color);
}
}
imagepng($resized_image, 'test-image-scaled.png');
?>
.
用当然的变量替换硬编码值......这是我使用你的图像和我的代码的结果:
(源: jejik.com
其他提示
ImageCopySampled()和透明度存在问题。看看关于php.net 的评论可能的解决方案。
不隶属于 StackOverflow