为什么WebImage.Resize会去除PNG透明度

6

使用MVC3/WebMatrix发布的WebImage。从文件路径加载以下图像:

示例图像 - 或者 - 输入图像描述

对其运行以下代码:

return new WebImage(path)
       .Resize(120, 265)
       .GetBytes("Png");

将图像中的透明度去除,并使用黑色代替:

Blacked out transparency

同样的情况也会发生在RotateRight()、RotateLeft()和FlipHorizontal()方法中。但是如果我不调用.Resize()方法:
return new WebImage(path)
        .GetBytes("Png");

图像被成功返回。

System.Web.WebImage应该是作为MVC3和/或WebMatrix的一部分提供的。 - Richard Slater
1
你能贴出你实际图片的链接吗? SO 使用的图片服务不幸地会重新压缩图片,所以如果你的特定图片有什么特殊之处,我们就无法看到它。 - Chris Haas
目前不行,因为我现在在家。然而上面的图片是用Paint.net创建的,并保存为24位PNG格式。 - Richard Slater
添加了一张示例图片,我可以用它来重现错误。 - Richard Slater
2个回答

2
您的图片是否为8位(索引色)? 当调整8位图像大小时,通常会将其从索引色转换为RGB,以使结果看起来更平滑。不更改颜色表就调整图像大小很少有好的结果。
如果图像已经是RGB(24位或更多),那么情况就有点复杂:调整大小算法应该如何处理图像边缘,在“透明”和“非透明”之间的边界?许多调整大小算法会在边界处执行类似于“平均两种颜色”的操作(再次使图像看起来更平滑),但大多数算法都没有透明度概念,更不用说PNG具有多个透明度级别的能力了。
因此,简短的答案是“这可能是一个错误”——而不是PNG功能的完整实现。
解决方案可能不存在,但我建议尝试以下方法:
  1. 如果可以选择,请保持8位颜色或提前转换为32位。
  2. 获取透明颜色或颜色索引。调整大小后,强制该值为透明。请注意,由于上述“平滑”,透明和非透明之间的边缘可能不是该颜色,并且可能看起来像黑色和您实际想要的任何颜色的混合物。
  3. 如果没有其他方法,您可能需要使用外部库来获得更多控制。

我知道使用WPF/System.Windows.Imaging.Media是可行的,所以在这件事上我可能不得不诉诸于大招。 - Richard Slater

0
你尝试使用方法Write()而不是GetBytes()吗?

Write() 在幕后不幸地调用了 GetBytes() - Chris Haas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接