System.Drawing.Bitmap から System.Runtime.InteropServices.Marshal.Copy で取り出した byte 配列から画素値を取り出す
Marshal.Copy についてはBitmapの内部データにアクセスする ( ソフトウェア ) - おきらくエンジニア - Yahoo!ブログを見て解決する.image っていうクラスを作って,getByte() メソッドを記述してみた.
private void getByte(Bitmap bmp) { // Bitmapの内部データにアクセスする // http://blogs.yahoo.co.jp/spike_spike690/4735887.html // Pixelデータにアクセスする領域を設定する Rectangle rect = new Rectangle(0, 0, imageSize.X, imageSize.Y); // BitmapDataクラスのインスタンスを生成し、LockBits関数でBitmapをLockする。 BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); // BitmapData内の各種項目を抜き出す。 IntPtr ptr = bmpData.Scan0; this.imageStride = Math.Abs(bmpData.Stride); // コピーするデータ量を設定.PixelFormat に関わらず stride * 高さ int bytes = this.imageStride * imageSize.Y; this.imageData = new byte[bytes]; // 確保したデータ配列にBitmap内のデータをコピー System.Runtime.InteropServices.Marshal.Copy(ptr, this.imageData, 0, bytes); // Bitmapのロックを解除する。 bmp.UnlockBits(bmpData); }
参照元との違いは,
- 画素値書き換えをしないから ImageLockMode.ReadOnly で読み出した
- カラー画像として盲目的に読み込む
this.imageData に byte が入った.getPixel() メソッドを作る.以下の3ページを参考にした.
public enum ColorIndex { Gray, Blue = 0, Green, Red }; public int getPixel(Point p, ColorIndex colorIndex) { return (int)imageData[p.X * 3 + p.Y * imageStride + (int)colorIndex]; }
LockBits() したときに PixelFormat.Format24bppRgb と指定していたから,3個ごとに読み出すため p.X を3倍している.