2011-11-17 102 views
2

我有一个位图,我试图对它应用一个alpha通道。这个alpha存在于一个二进制文件中,并且我能够读取它中的所有字节并获取正确的值。当我测试Color.FromArgb时也会给出正确的颜色。但是,当我在我的位图上调用SetPixel时,它不起作用 - 它没有发生任何事情。我究竟做错了什么?Bitmap.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的回答速度,但他的答案没有工作,直到我也用维塔利的建议并在我锁定位之前做了MakeTransparent()

(新)最终答案 在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

什么格式保存你的形象? – vcsjones

+0

图像没有被保存,它的全部都在内存中完成,因此可以预览。 –

回答

3

也许是一个预乘α与非预乘alpha的问题。

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

+0

如果我试图设置每个字节上的字母(使用LockBits),我正在修改第一个字节,然后是每个第三个字节,对吗?我按照此处给出的示例进行操作:http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx –

+0

由于您有4个通道,每个通道8位,因此您需要修改每4个字节。 – CodesInChaos

+0

有一个很好的机会,alpha通道是第四个字节。应该很容易测试。 – phoog

2

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

VB .NET picture GetPixel & SetPixel: Include alpha?

+0

你的确也工作得很好,但我需要更快的东西(我以后可能会使用一些非常大的图像来制作动画片动画) –

+0

呵呵。事实证明,我需要使用你的建议,使其透明,以及每个像素都有一个alpha。我希望我能接受你们的答案,因为他们把我带到了那里。 –

相关问题