Bitmap.SetPixel未设置正确的颜色

时间:2011-11-17 20:15:31

标签: c# .net

我有一个位图,我正在尝试将Alpha通道应用于它。这个alpha存在于二进制文件中,我能够读取其中的所有字节并获得正确的值。 Color.FromArgb在测试时也会给出正确的颜色。但是,当我在我的位图上调用SetPixel时,它不起作用 - 它就像没有发生任何事情一样。我做错了什么?

如果相关,则使用SharpZibLib从流创建位图。

for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
         var c = imageData.GetPixel(x, y);
         var a = alphaMask[y*width + x];

         imageData.SetPixel(x, y, Color.FromArgb(a, c));
    }
}

(OLD)最终答案:(有副作用,见新的最终解决方案) 事实证明,我需要CodeInChaos答案的速度,但是在我使用Vitaliy的建议并且在锁定位之前做MakeTransparent()时,他的答案才起作用。

(NEW)最终答案 在24位位图上使用MakeTransparent()实际上会产生一些不良后果。 MakeTransparent()寻找特定的浅灰色,以在位图中生成透明色。如果此颜色不存在,则选择最接近的颜色,并将其设置为ARGB(00,00,00,00)。如果您通过将Alpha更改为255来使其变为非透明,则无论“浅灰色”的“最接近”颜色是什么,您都会在图像上获得黑色像素。如果您需要添加Alpha通道,我建议使用以下方法“升级”您的图片:

            var bmp = new Bitmap(imageStream);
            var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

            var upgradedBmp = bmp.Clone(rect, PixelFormat.Format32bppArgb);
            bmp.Dispose();

这会添加Alpha通道而不会将颜色替换为透明,并且从长远来看会占用最少的内存。

2 个答案:

答案 0 :(得分:3)

可能是预乘的alpha与非预乘的alpha问题。

但我建议完全避免GetPixel / SetPixel。他们非常慢。锁定图像数据并直接在其上工作。

答案 1 :(得分:2)

在调用SetPixel()之前,您需要调用MakeTransparnet()。

请参阅VB .NET picture GetPixel & SetPixel: Include alpha?