我被this discussion的图像缩放所吸引,后来发现我用来从上传的图像创建缩略图的PHP代码遇到了同样的问题。我决定尝试在底部附近发布的PHP修补程序(将伽玛值从2.2转换为1.0,调整图像大小,将伽玛值从1.0转换回2.2)。这可以解决本文中提到的问题,但是对代码的这种修改具有消除PNG alpha通道透明度的不幸副作用。
以下是我对伽马校正的代码。
<?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通道透明度?
示例图片:
在尝试更正伽玛之前,您可以看到透明度正常。 (查看透明度的最简单方法是检查包裹在图像周围的段落标记,并通过FireBug或类似方法添加背景:black;到其样式属性。)
original image http://ender.hosting.emarketsouth.com/images/test-image.png no gamma correction http://ender.hosting.emarketsouth.com/images/test-image-resized-no-gamma.png gamma corrected - no transparency http://ender.hosting.emarketsouth.com/images/test-image-resized.png
答案 0 :(得分:2)
这是一些有用的代码。基本上,它分离出alpha通道,使用伽马校正调整图像大小,调整Alpha通道的大小,而不用伽马校正,然后通过alpha通道复制到通过伽马校正完成的已调整大小的图像。
我的猜测是imagegammacorrect()函数有一个bug。也许gamma只适用于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');
?>
将硬编码值替换为变量当然......这是我使用您的图像和代码得到的结果:
Resized image http://www.jejik.com/sander/test-image-scaled.png
答案 1 :(得分:-1)
imagecopyresampled()和透明度存在问题。请查看this comment on php.net以获取可能的解决方案。