簡體   English   中英

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

[英]Alpha masking in c# System.Drawing?

我正在嘗試使用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輸出。 我確定你可以改變它,以便在需要時使用面具的紅色或alpha通道。

根據您的要求,這可能會更容易:

  • 反轉遮罩,使圓圈透明,其余部分來自輸入位圖中未使用的顏色(例如紅色)
  • 使用Graphics.FromImage(image).DrawImage(mask)在圖像上繪制蒙版...
  • 在圖像上將蒙版顏色設置為透明(image.MakeTransparent(Color.Red))

此方法的唯一缺點是它需要您確保圖像中未使用蒙版顏色。 我不知道這比手動方式更慢還是更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM