问题描述
我想绘制图像,与源位图
和alpha掩码位图
,使用 System.Drawing.Graphics
对象。
目前,我环路X和Y,并使用 GetPixel
和的setPixel
写的源颜色和掩码阿尔法第三位图
,然后渲染。
然而,这是非常低效的,我不知道是否有实现这一目标的方式更快
I'm trying to draw an image, with a source Bitmap
and an alpha mask Bitmap
, using the System.Drawing.Graphics
object.At the moment I loop X and Y and use GetPixel
and SetPixel
to write the source color and mask alpha to a third Bitmap
, and then render that.However this is very inefficient and I am wondering if there is an faster way to achieve this?
看起来像这样之后我的影响:
The effect I'm after looks like this:
网格模式代表透明度;你可能知道。
The grid pattern represents transparency; you probably knew that.
推荐答案
是的,更快的方式做到这一点是使用 Bitmap.LockBits
并使用指针运算来检索值,而不是 GetPixel
和的setPixel
。不利的一面,当然,是你必须使用不安全的代码;如果你犯了一个错误,你可以在你的程序会导致一些非常糟糕的崩溃。但是,如果你保持它的简单和自足的,应该没事(嘿嘿,如果我能做到,你也能做到)。
Yes, the faster way to do this is to use Bitmap.LockBits
and use pointer arithmetic to retrieve the values instead of GetPixel
and SetPixel
. The downside, of course, is that you have to use unsafe code; if you make a mistake, you can cause some really bad crashes in your program. But if you keep it simple and self-contained, it should be fine (hey, if I can do, you can do it too).
例如,你可以做这样的事情(未测试,使用风险自负):
For example, you could do something like this (not tested, use at your own risk):
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通道如果需要的话。
This example derives the alpha channel in the output from the blue channel in the mask image. I’m sure you can change it to use the mask’s red or alpha channel if required.
这篇关于阿尔法掩蔽在c#System.Drawing中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!