【问题标题】:Why does System.Drawing.Graphics blank the RGB channels when Alpha==0?当 Alpha==0 时,为什么 System.Drawing.Graphics 会空白 RGB 通道?
【发布时间】:2014-10-03 21:02:40
【问题描述】:

对于我正在开发的用于处理具有 Alpha 通道的图像的程序,这已成为一个严重的障碍。 我拥有的许多图像都包含颜色信息,其中 Alpha 通道是完全透明的,但是一旦我尝试将它们加载到 System.Drawing.Graphics 中,它就会将 Alpha 为 0 的任何内容更改为 Alpha 为 0 的黑色.

这是该问题的基本示例。 我环顾四周,试图找到一个原因、答案或解决方法,但我没有找到任何暗示这个问题的东西。 任何在这一点上的帮助将不胜感激。

var myTestTransparentColor = Color.FromArgb(0, 255, 128, 64);
var image = new Bitmap(135, 135, PixelFormat.Format32bppArgb);

using (var g = Graphics.FromImage(image))
{
    g.Clear(myTestTransparentColor);
}

var color = image.GetPixel(0, 0);

Debug.Assert(color == myTestTransparentColor, "channels must match original");

编辑:

经过进一步测试,我并没有真正看到使用 System.Drawing.Graphics 的方法,所以我唯一不是真正答案的解决方案是完全避免使用 System.Drawing.Graphics。浏览我的代码,看起来我可以避免它。 在使用 System.Drawing.Graphics 绘制形状、在图像上植入文本多年之后,我发现 System.Drawing.Graphics 有这样一个明显的缺点很烦人。

我仍然想知道我是否可以使用 System.Drawing.Graphics 并保持我的 ARGB 完好无损,但我想我现在可以不用它。

【问题讨论】:

  • 我不知道,但如果 System.Drawing.Graphics 在幕后使用预乘 alpha 颜色 (cgdirector.com/quick-tip-straight-alpha-vs-premultiplied-alpha) 并因此提供您所看到的行为,我不会感到惊讶。跨度>
  • @lzcd 这就是我的想法,但 Format32bppPArgb 不应该用于预乘,而不是 Format32bppArgb?
  • 哇,这很奇怪。我刚刚做了一些测试,包括查看 lockbit 结构的字节,并且必须确认您的发现。 Clear 和 FillRectangle 似乎都在创建,什么? like 预乘像素?并非如此:将颜色更改为 (10, 255, 128, 64) 会导致 (10,255,127,76)。奇怪..
  • 好的,这似乎与thisthis有关

标签: c# c#-4.0 graphics colors alpha-transparency


【解决方案1】:

我认为 Vincent Povirk 在这里适当地回答了我的问题:Drawing PixelFormat32bppPARGB images with GDI+ uses conventional formula instead of premultiplied one

“前景图像的格式无关紧要(假设它具有 alpha),因为您将其设置为 Gdiplus::Color。颜色值定义为非预乘,因此 gdiplus 将分量乘以清除前景图像时的 alpha 值。另一种方法是颜色值根据渲染目标的格式具有不同的含义,这种方式很疯狂。”

“如果您真的想要对渲染进行这种级别的控制,则必须锁定位图位并自己完成。”

所以,我自己做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-17
    • 2012-10-03
    • 2013-02-18
    • 1970-01-01
    • 2021-04-25
    • 2020-09-25
    • 2019-09-05
    • 1970-01-01
    相关资源
    最近更新 更多