我有一个位图,我正在尝试将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通道而不会将颜色替换为透明,并且从长远来看会占用最少的内存。
答案 0 :(得分:3)
可能是预乘的alpha与非预乘的alpha问题。
但我建议完全避免GetPixel
/ SetPixel
。他们非常慢。锁定图像数据并直接在其上工作。
答案 1 :(得分:2)
在调用SetPixel()之前,您需要调用MakeTransparnet()。