我正在尝试使用Bitmap
对象绘制带有源Bitmap
和alpha蒙版System.Drawing.Graphics
的图像。
目前我循环X和Y并使用GetPixel
和SetPixel
将源颜色和掩码alpha写入第三个Bitmap
,然后渲染它。
然而,这是非常低效的,我想知道是否有更快的方法来实现这一目标?
我所追求的效果如下:
网格图案代表透明度;你可能知道的。
答案 0 :(得分:15)
是的,更快的方法是使用Bitmap.LockBits
并使用指针算法来检索值,而不是GetPixel
和SetPixel
。当然,缺点是你必须使用不安全的代码;如果你犯了一个错误,你可以在程序中造成一些非常糟糕的崩溃。但如果你保持简单和自足,它应该没问题(嘿,如果我能做到,你也可以这样做)。
例如,您可以执行以下操作(未经测试,使用风险自负):
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通道。我确定如果需要,你可以改变它以使用面具的红色或alpha通道。
答案 1 :(得分:5)
根据您的要求,这可能会更容易:
此方法的唯一缺点是需要您确保图像中未使用蒙版颜色。 我不知道这比手动方式更慢还是更快。