imagecopyresampled()在透明的PNG中引入伪像 [英] imagecopyresampled() introduces artifacts in transparent PNG

查看:182
本文介绍了imagecopyresampled()在透明的PNG中引入伪像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm adding a transparent PNG watermark to an image. The watermark is high resolution so before overlaying it in the original image I resize it. This seems to introduce some artifacts in the watermark that I haven't found a way to avoid.

原始图片:

调整大小后的图像(请看字母之间的水平线状污点"):

Resized image (look at the horizontal line-like "dirt" between letters"):

调整大小后的图像的缩放比例(不透明),以阐明我在字母之间的污垢"的含义.我已经使用选择工具清理并删除了"s"和"t"之间的区域(在新标签页中打开以查看更清晰的完整尺寸):

Zoom of resized image (not transparent) to clarify what I mean by the "dirt" between the letters. The area between "s" and "t" I've cleaned with the select tool and delete (open in new tab to see full size where it's more clear):

这是我正在使用的代码:

Here's the code I'm using:

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

关于造成这些伪像的原因有什么想法?

Any idea on what is causing the artifacts?

推荐答案

正如我在回应SørenLøvborgs的评论中所写的那样,这看起来很简单[GD/imagecopyresampled()][1]的问题无法避免. 具有透明PNG的GD质量问题具有相同的问题.

As I wrote in my comment in response to Søren Løvborgs answer it looks like it's simply [an issue with GD/imagecopyresampled()][1] that can not be easily avoided. GD Quality Issue with Transparent PNGs has the same issue.

可以使用SørenLøvborgs建议的解决方法,但请记住,由于两次调整原始图像的大小可能会导致明显的质量下降.

It's possible to use Søren Løvborgs suggested workaround, just keep in mind that it may introduce noticable quality reduction due to resizing the original image twice.

我建议在覆盖之前使用照片编辑器调整水印的大小.这种方法不那么灵活,但是可以保持图像质量并且不会增加任何噪点.

I suggest using a photo editor to resize the watermark before overlaying instead. This isn't as flexible, but it will keep the image quality and not add any noise.

这篇关于imagecopyresampled()在透明的PNG中引入伪像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆