imagecopyresampled()在透明PNG中引入了工件

问题描述 投票:0回答:3

我正在为图像添加透明的PNG水印。水印是高分辨率的,因此在将其重叠在原始图像中之前,我将其调整大小。这似乎在水印中引入了一些我没有找到避免方法的文物。

原始图片:

调整大小的图像(查看字母之间的水平线状“污垢”):

缩放调整大小的图像(不透明),以澄清我的意思是字母之间的“污垢”。 “s”和“t”之间的区域我已使用选择工具清除并删除(在新选项卡中打开以查看更清晰的完整大小):

这是我正在使用的代码:

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);
}

什么导致工件的任何想法?

php gd
3个回答
2
投票

这似乎不会出现在黑色背景上,因此另一个黑客将是在调整大小之前反转图像并在之后再次执行

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);

2
投票

正如我在回答SørenLøvborgs的评论中写的那样回答它看起来很简单[GD / imagecopyresampled()][1]的问题不容易避免。 GD Quality Issue with Transparent PNGs也有同样的问题。

可以使用SørenLøvborgs建议的解决方法,请记住,由于两次调整原始图像的大小,它可能会引入显着的质量降低。

我建议使用照片编辑器来重新调整水印,然后重叠。这不是那么灵活,但它会保持图像质量而不会增加任何噪音。


1
投票

好的,首先,这是你的“脏”测试图像,RGB通道(上图)和alpha通道(下图)分开:

我用蓝色替换了纯白色(#FFFFFF)/ 100%透明以突出斑点。

如您所见,GD为RGB通道和Alpha通道添加了斑点。

在没有检查GD代码的情况下,我猜测它是由舍入误差引起的,导致一些像素被1或2关闭。

我注意到您在源PNG中有一个嵌入的颜色配置文件。尝试删除;人工制品可能是由GD进行色彩校正引起的。 (在Photoshop中,您应该使用Save for Web。)

否则,我无法在不修复GD代码的情况下建议解决此问题的方法,但是,我可以建议一个可能有效的脏方法:

不是将水印调整为目标图像大小,而是将其覆盖在目标图像上,您可以将目标图像调整为水印大小,覆盖水印,删除Alpha通道,然后调整大小到旧的目标图像大小。这样,您可以避免在具有Alpha通道的情况下调整任何图像的大小,这可以避免可见的伪像。

© www.soinside.com 2019 - 2024. All rights reserved.