如何使用“透明白色”绘制位图区域?

时间:2010-05-21 14:45:48

标签: c# graphics

我想用“透明白色”替换位图矩形区域中的所有像素 - 即a = 0,b = 255,r = 255,g = 255。

FillRectangle不这样做 - 给定透明画笔,现有像素不变。

我是否需要为矩形中的每个像素单独使用SetPixel?

6 个答案:

答案 0 :(得分:13)

您必须设置Graphics.CompositingMode属性。例如:

protected override void OnPaint(PaintEventArgs e) {
    var img = Properties.Resources.Chrysanthemum;
    e.Graphics.DrawImage(img, 0, 0);
    e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
    using (var br = new SolidBrush(Color.FromArgb(0, 255, 255, 255))) {
        e.Graphics.FillRectangle(br, new Rectangle(50, 50, 100, 100));
    }
}

您使用的实际颜色无关紧要,您将获得一个alpha为0的黑色矩形。

答案 1 :(得分:4)

我相信您需要使用SetPixel(或直接设置颜色值的等效方法)来使像素为“透明白色”。

您可以使用Graphics.Clear方法设置颜色或像素,但不能使用它将它们设置为透明和颜色。我试过这个来设置位图的一部分像素:

using (Graphics g = Graphics.FromImage(theBitmap)) {
  g.Clip = new Region(new Rectangle(10, 10, 80, 80));
  g.Clear(Color.FromArgb(0, Color.White));
}

区域中的像素最终为“透明黑色”:0,0,0,0。即使在清除之前绘制纯白色矩形也无济于事。当颜色中的alpha为零时,其他颜色分量也为零。

使用像1这样几乎透明的alpha工作正常,像素最终变成“几乎透明的白色”:1,255,255,255。

答案 2 :(得分:3)

如果使用复合绘画方法,那么alpha将用于混合颜色,因此不会发生任何事情。

如果要设置位图,请使用所需背景的数据创建位图,或使用LockBits设置背景以操纵数据集。

您也可以使用带有相应标志的bitblt方法,但我不知道如何将其转换为托管代码。

答案 3 :(得分:1)

重要提示:

确保在创建图像时执行此操作

mainImage = new Bitmap(totalWidth, maxHeight, PixelFormat.Format32bppARgb);

而不是

mainImage = new Bitmap(totalWidth, maxHeight, PixelFormat.Format32bppRgb);

它会为你省去一些麻烦。不要假设32位表示alpha通道; - )

答案 4 :(得分:0)

  

FillRectangle不这样做 - 给定透明画笔,现有像素不变。

有道理,因为你用0%不透明度绘图。 :)

Control的快速解决方案是一个颜色键。您可以将控件的键颜色设置为特定颜色(即洋红色);然后,所有具有此颜色的像素将呈现为透明。 (当然,如果控件支持它。)

那个,或者bitmap.MakeTransparent(颜色)用于一般目的。问题是指定的颜色是透明的,因此您必须选择图像中不存在的颜色。 (这里有另一个例子:http://msdn.microsoft.com/en-us/library/ms172507%28v=VS.80%29.aspx

编辑: 最后,其他评论中提到的LockBits()方法可能就是您所寻求的。一旦了解宽度和步幅值如何相互作用,就可以在尽可能低的水平上操纵图像。 这是一个一般例子:http://www.bobpowell.net/lockingbits.htm 只需确保图像支持透明度(请参阅PixelFormat),然后使用适当的模式锁定图像(即PixelFormat.Format32bppArgb),遍历每个像素,读取字节,写入新颜色等。

答案 5 :(得分:0)

这个小黑客应该做的伎俩:

Graphics g = Graphics.FromImage(myBitmap);
g.SetClip(new RectangleF(10, 10, 20, 20));
g.Clear(Color.Transparent);
g.RestoreClip();
g.Dispose();