web-dev-qa-db-ja.com

C#でピクセルレベルで画像を操作する方法

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

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

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

45
Kamil Zadora

速度が必要な場合は、 LockBits 。 Bob Powellによる優れたチュートリアルについては、こちらをご覧ください。。いくつかを編集したいだけなら、 GetPixel / SetPixel はあなたが望むことをするはずです。

50
Marc Gravell

サンプルコードルーチン(単純なマージおよび比較機能にこれを使用します。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に注意し、それを使用してメモリ内の画像を直接変更します。パフォーマンスが懸念される場合は、私が投稿したものではなく、それを見ることをお勧めします。ありがとう、マーク!

15
mattlant

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

5
Grank

パフォーマンスが重要な場合、LockBitsに代わるもう1つの代替手段がマネージDirectXです。

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

Lockbitsと同様に、安全でないキーワード/コンパイラスイッチを使用する必要がありますが、高性能なピクセルレベルのアクセスが可能です。

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

3
Ash