Php imagecopyresampled()在透明PNG中引入瑕疵
我正在向图像添加一个透明的PNG水印。水印是高分辨率的,所以在将其覆盖到原始图像之前,我会调整其大小。这似乎在水印中引入了一些我无法避免的瑕疵 原始图像: 调整大小的图像(查看字母之间的水平线,如“污垢”): 缩放已调整大小的图像(非透明),以澄清我所说的字母之间的“污垢”是什么意思。我已使用“选择”工具清理了“s”和“t”之间的区域并将其删除(在“新建”选项卡中打开以查看更清晰的全尺寸): 以下是我使用的代码:Php imagecopyresampled()在透明PNG中引入瑕疵,php,gd,Php,Gd,我正在向图像添加一个透明的PNG水印。水印是高分辨率的,所以在将其覆盖到原始图像之前,我会调整其大小。这似乎在水印中引入了一些我无法避免的瑕疵 原始图像: 调整大小的图像(查看字母之间的水平线,如“污垢”): 缩放已调整大小的图像(非透明),以澄清我所说的字母之间的“污垢”是什么意思。我已使用“选择”工具清理了“s”和“t”之间的区域并将其删除(在“新建”选项卡中打开以查看更清晰的全尺寸): 以下是我使用的代码: function resizeImage($image_filename,
function resizeImage($image_filename, $out_filename, $width, $height){
// Get image info
$image_info = @getimagesize($image_filename);
if ($image_info == false) return false;
$org_width = $image_info[0];
$org_height = $image_info[1];
$image_type = $image_info[2];
// Open image
if ($image_type == IMAGETYPE_JPEG) $org_image = @imagecreatefromjpeg($image_filename);
else if ($image_type == IMAGETYPE_GIF) $org_image = @imagecreatefromgif($image_filename);
else if ($image_type == IMAGETYPE_PNG) $org_image = @imagecreatefrompng($image_filename);
else return false;
// Open stream for resized image
$resized_image = @imagecreatetruecolor($width, $height);
if ($resized_image == false) return false;
// Handle transparency in PNGs
if ($image_type == IMAGETYPE_PNG){
$transparent = imagecolorallocatealpha($resized_image, 255, 255, 255, 127);
imagefilledrectangle($resized_image, 0, 0, $width, $height, $transparent);
imagealphablending($resized_image, false);
imagesavealpha($resized_image, true);
}
// Resize
$resize_result = @imagecopyresampled($resized_image, $org_image, 0, 0, 0, 0, $width, $height, $org_width, $org_height);
// Free original image
@imagedestroy($org_image);
// Save
if ($image_type == IMAGETYPE_JPEG) $save_result = imagejpeg($resized_image, $out_filename, 90); // 90 = compression
else if ($image_type == IMAGETYPE_GIF) $save_result = imagegif($resized_image, $out_filename);
else if ($image_type == IMAGETYPE_PNG) $save_result = imagepng($resized_image, $out_filename, 0);
// Free resized image
if ($resize_result) @imagedestroy($resized_image);
return ($resize_result && $save_result);
}
知道是什么导致了这些伪影吗?好的,首先,这是您的“脏”测试图像,RGB通道(上图)和alpha通道(下图)分开: 我用蓝色代替了纯白(
#FFFFFF
)/100%透明以突出斑点
如您所见,GD将散斑添加到RGB通道和alpha通道
在没有检查GD代码的情况下,我猜测它是由舍入错误引起的,导致一些像素偏离1或2
我注意到在源PNG中有一个嵌入的颜色配置文件。请尝试删除它;伪影可能是由于GD进行颜色校正造成的。(在Photoshop中,您应该使用Save for Web。)
否则,我不能建议一种不修复GD代码的方法来解决这个问题,但是,我可以建议一种肮脏的解决方法,它可能会起作用:
与将水印大小调整为目标图像大小,然后将其覆盖在目标图像上不同,您可以将目标图像大小调整为水印大小,覆盖水印,删除alpha通道,然后调整为旧的目标图像大小。这样可以避免在具有alpha通道的图像中调整任何图像的大小,从而避免可见的伪影cts.正如我在回复瑟伦·勒沃格的回答时所写的那样,看起来这只是[GD/
imagecopyresampled()]的一个问题][1]
无法轻易避免。也有同样的问题
可以使用søren Løvborgs建议的解决方法,但请记住,由于将原始图像大小调整两次,可能会导致明显的质量降低
我建议在叠加之前使用照片编辑器来调整水印的大小。这不是很灵活,但它可以保持图像质量,并且不会添加任何噪声。这似乎不会发生在黑色背景上,因此另一种方法是在调整大小之前反转图像,然后再进行调整
imagefilter($org_image, IMG_FILTER_NEGATE);
imagecopyresampled($resized_image, $org_image, 0, 0, 0, 0, $width, $height, $org_width, $org_height);
imagefilter($resized_image, IMG_FILTER_NEGATE);
我没有看到任何人工制品?它们不是很明显,但是100%透明的区域(在原图中)字母之间包含一些模糊的灰线/灰点。是的,没关系,用更好的显示器看图片,它们是非常可见的。我尝试在Photoshop中为web保存-没有变化。这似乎只是GD/
imagecopyresampled()
的问题(例如,我现在看到其他人也有同样的问题).imagecopyresized()
似乎可以更好地处理透明度,但它的重采样不好,会产生一些非常锯齿状的边缘。