46

C# でピクセル レベルで画像を操作するにはどうすればよいですか?

各ビットマップ ピクセルの RGB 値を個別に読み取り/変更できるようにする必要があります。

コードサンプルをいただければ幸いです。

4

4 に答える 4

51

速度が必要な場合は、LockBitsBob Powell による優れたウォークスルーについては、こちらを参照してください。いくつかを編集したいだけなら、GetPixel / SetPixelでやりたいことができます。

于 2008-10-10T07:19:05.583 に答える
16

サンプル コード ルーチン (私はこれを単純なマージおよび比較機能に使用します。2 つの画像を取得し、2 つの画像の違いをグレースケール トーン レベルとして示す 3 つ目のグレースケール画像を生成します。暗いほど、違いが大きくなります。):

    public static Bitmap Diff(Bitmap src1, Bitmap src2, int x1, int y1, int x2, int y2, int width, int height)
{
    Bitmap diffBM = new Bitmap(width, height, PixelFormat.Format24bppRgb);

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //Get Both Colours at the pixel point
            Color col1 = src1.GetPixel(x1 + x, y1 + y);
            Color col2 = src2.GetPixel(x2 + x, y2 + y);

            // Get the difference RGB
            int r = 0, g = 0, b = 0;
            r = Math.Abs(col1.R - col2.R);
            g = Math.Abs(col1.G - col2.G);
            b = Math.Abs(col1.B - col2.B);

            // Invert the difference average
            int dif = 255 - ((r+g+b) / 3);

            // Create new grayscale RGB colour
            Color newcol = Color.FromArgb(dif, dif, dif);

            diffBM.SetPixel(x, y, newcol);

        }
    }

    return diffBM;
}

Marc の投稿では、LockBits を使用し、それを使用してメモリ内の画像を直接変更しています。パフォーマンスが懸念される場合は、私が投稿したものではなく、それを見ることをお勧めします。ありがとうマルク!

于 2008-10-10T07:31:28.287 に答える
5

System.Drawing.Bitmap には、System.Drawing.Color 構造体を返す GetPixel(int x, int y) パブリック メソッドがあります。この構造体にはバイト メンバー R、G、B、および A があり、これらを直接変更して、Bitmap で SetPixel(Color) を再度呼び出すことができます。
残念ながら、これは比較的遅くなりますが、C# で行うのが最も簡単な方法です。個々のピクセルを頻繁に操作していて、パフォーマンスが不足していて、より高速なものが必要な場合は、LockBits を使用できます。ただし、その色深度とタイプのビット構造を理解する必要があるため、はるかに複雑です。 、ビットマップのストライドなどを操作します...必要がある場合は、適切なチュートリアルを見つけてください! ウェブ上にいくつかあります。「C# LockBits」をグーグルで検索してください。

于 2008-10-10T07:27:53.240 に答える
3

パフォーマンスが重要な場合は、LockBits の別の代替手段としてマネージ DirectX があります。

詳細については、以前のスタック オーバーフローの質問C# でのグラフィックスのレンダリングを参照してください。

ロックビットと同様に、unsafe キーワード/コンパイラ スイッチを使用する必要がありますが、高性能のピクセル レベルのアクセスが得られます。

また、通常の Bitmap クラスと PictureBox コントロールを使用する場合と比較して、DirectX バックバッファリングにより、より高いパフォーマンスの画面レンダリングも得られます。

于 2008-10-10T08:33:06.900 に答える