我正在嘗試使用System.Drawing.Graphics
對象來繪製圖像,其中源Bitmap
和alpha掩碼Bitmap
。 此刻我循環X和Y,並使用GetPixel
和SetPixel
將源顏色和遮罩alpha寫入第三個Bitmap
,然後再渲染它。 但是,這是非常低效的,我想知道是否有更快的方法來實現這一目標?Alpha遮罩在c#System.Drawing?
長相後,我很喜歡這樣的效果:
網格圖案表示的透明度;你可能知道這一點。
我正在嘗試使用System.Drawing.Graphics
對象來繪製圖像,其中源Bitmap
和alpha掩碼Bitmap
。 此刻我循環X和Y,並使用GetPixel
和SetPixel
將源顏色和遮罩alpha寫入第三個Bitmap
,然後再渲染它。 但是,這是非常低效的,我想知道是否有更快的方法來實現這一目標?Alpha遮罩在c#System.Drawing?
長相後,我很喜歡這樣的效果:
網格圖案表示的透明度;你可能知道這一點。
是的,更快的方法是使用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通道。
我仍然需要迭代像素,對吧? – Origamiguy 2010-09-06 20:56:19
是的,但速度非常快。任何其他可能使用的實現都必須遍歷像素。 – Timwi 2010-09-06 20:57:18
嗯,它的工作原理,它肯定比我以前的方法更快,謝謝! – Origamiguy 2010-09-06 22:46:05
根據您的要求,這可能是更容易:
此方法的唯一缺點是它需要您確保圖像中未使用遮罩顏色。 我不知道這是否比手動方式更慢或更快。
既然你說你正在使用System.Drawing.Graphics,這可能是無關緊要的,但是這裏有一個WPF中不透明蒙板的鏈接,它將利用硬件加速:http://msdn.microsoft.com/ en-us/library/system.windows.media.drawinggroup.opacitymask.aspx – Douglas 2010-09-06 21:11:27
偏離主題,但令人着迷 - 謝謝! – Origamiguy 2010-09-06 21:14:08