在c#System.Drawing中使用Alpha掩码?

我正在尝试使用System.Drawing.Graphics对象绘制带有源Bitmap和alpha蒙版Bitmap的图像。 目前我循环X和Y并使用GetPixelSetPixel将源颜色和掩码alpha写入第三个Bitmap ,然后渲染它。 然而,这是非常低效的,我想知道是否有更快的方法来实现这一目标?

我之后的效果看起来像这样:

效果我在追求

网格图案代表透明度; 你可能知道这一点。

是的,更快的方法是使用Bitmap.LockBits并使用指针算法来检索值而不是GetPixelSetPixel 。 当然,缺点是你必须使用不安全的代码; 如果你犯了一个错误,你可以在你的程序中造成一些非常糟糕的崩溃。 但是,如果你保持简单和自足,它应该没问题(嘿,如果我能做到,你也可以做到)。

例如,您可以执行以下操作(未经测试,使用风险自负):

 Bitmap mask = ...; Bitmap input = ...; Bitmap output = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppArgb); var rect = new Rectangle(0, 0, input.Width, input.Height); var bitsMask = mask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var bitsInput = input.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var bitsOutput = output.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); unsafe { for (int y = 0; y < input.Height; y++) { byte* ptrMask = (byte*) bitsMask.Scan0 + y * bitsMask.Stride; byte* ptrInput = (byte*) bitsInput.Scan0 + y * bitsInput.Stride; byte* ptrOutput = (byte*) bitsOutput.Scan0 + y * bitsOutput.Stride; for (int x = 0; x < input.Width; x++) { ptrOutput[4 * x] = ptrInput[4 * x]; // blue ptrOutput[4 * x + 1] = ptrInput[4 * x + 1]; // green ptrOutput[4 * x + 2] = ptrInput[4 * x + 2]; // red ptrOutput[4 * x + 3] = ptrMask[4 * x]; // alpha } } } mask.UnlockBits(bitsMask); input.UnlockBits(bitsInput); output.UnlockBits(bitsOutput); output.Save(...); 

此示例从掩模图像中的蓝色通道输出α值通道。 我确定你可以改变它,以便在需要时使用面具的红色或alpha通道。

根据您的要求,这可能会更容易:

  • 反转蒙版,使圆圈透明,其余部分来自输入位图中未使用的颜色(例如红色)
  • 使用Graphics.FromImage(image).DrawImage(mask)在图像上绘制蒙版…
  • 在图像上将蒙版颜色设置为透明(image.MakeTransparent(Color.Red))

此方法的唯一缺点是它需要您确保图像中未使用蒙版颜色。 我不知道这比手动方式更慢还是更快。