C#でピクセルレベルで画像を操作するにはどうすればよいですか?
各ビットマップピクセルRGB値を個別に読み取り/変更できる必要があります。
コードサンプルをいただければ幸いです。
サンプルコードルーチン(単純なマージおよび比較機能にこれを使用します。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に注意し、それを使用してメモリ内の画像を直接変更します。パフォーマンスが懸念される場合は、私が投稿したものではなく、それを見ることをお勧めします。ありがとう、マーク!
System.Drawing.Bitmapには、System.Drawing.Color構造体を返すGetPixel(int x、int y)パブリックメソッドがあります。その構造体にはバイトメンバR、G、B、およびAがあり、これらを直接変更してから、ビットマップでSetPixel(Color)を再度呼び出します。
残念ながら、それは比較的遅くなりますが、C#でそれを行う最も簡単な方法です。個々のピクセルを頻繁に使用していて、パフォーマンスが不足していて、より高速なものが必要な場合は、LockBitsを使用できます。 、そしてビットマップのストライドとそうでないもので動作します...ので、それが必要であるとわかったら、良いチュートリアルを見つけてください!ウェブ上にはいくつかのツールがありますが、グーグルの「C#LockBits」を読むと、読む価値のある半ダースが得られます。
パフォーマンスが重要な場合、LockBitsに代わるもう1つの代替手段がマネージDirectXです。
詳細については、前述のスタックオーバーフローの質問C#でのグラフィックのレンダリングを参照してください。
Lockbitsと同様に、安全でないキーワード/コンパイラスイッチを使用する必要がありますが、高性能なピクセルレベルのアクセスが可能です。
また、通常のビットマップクラスとPictureBoxコントロールを使用する場合と比較すると、DirectXバックバッファリングを介したより高いパフォーマンスのスクリーンレンダリングが得られます。