19

Bitmapオブジェクトを使用して、ソースとアルファマスクBitmapを使用して画像を描画しようとしていSystem.Drawing.Graphicsます。現時点では、X と Y をループし、 と を使用GetPixelSetPixelてソース カラーとマスク アルファを 3 番目の に書き込み、Bitmapそれをレンダリングします。ただし、これは非常に非効率的であり、これを達成するためのより速い方法があるかどうか疑問に思っていますか?

私が求めている効果は次のようになります。

私が求めている効果

グリッド パターンは透明度を表します。あなたはおそらくそれを知っていました。

4

2 に答える 2

16

はい、これを行うより速い方法は、と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(...);

この例では、マスク イメージのチャネルから出力のアルファ チャネルを取得します。必要に応じて、マスクの赤またはアルファ チャネルを使用するように変更できると確信しています。

于 2010-09-06T20:50:58.633 に答える
5

要件によっては、これははるかに簡単な場合があります。

  • 円が透明になり、残りが入力ビットマップで使用されていない色(例の赤など)からのものになるように、マスクを反転します。
  • Graphics.FromImage(image).DrawImage(mask)..を使用して、画像の上にマスクを描画します。
  • 画像のマスクカラーを透明に設定します(image.MakeTransparent(Color.Red))

この方法の唯一の欠点は、画像でマスクの色が使用されていないことを確認する必要があることです。これが手動の方法より遅いか速いかはわかりません。

于 2011-09-29T14:47:03.547 に答える