| ■No100273 (radian さん) に返信 > 2022/07/14(Thu) 15:57:03 編集(投稿者) > > ■No100272 (まさお さん) に返信 >>幅が4の倍数ではない201×100(仮)のイメージデータ(カラー)の描画をしたいのですがうまくいきません。 >>現在、下記のようにやっていますがMarshal.Copyのところでエラーになってしまいます。 >>(エラー:'保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。') >>イメージデータを200×100にして下記引数の201を200にすると期待する描画ができます。 >> >>Bitmap bitmap = new Bitmap(201, 100, 204, PixelFormat.Format24bppRgb, IntPtr.Zero)) >>BitmapData bitmapData = bitmap.LockBits( >> new Rectangle(0, 0, 201, 100), >> ImageLockMode.WriteOnly, >> PixelFormat.Format24bppRgb); >>Marshal.Copy(scan0, 0, bitmapData.Scan0, scan0.Length); // ここでエラー > > とりあえずデバッグして scan0.Lengthと、bitmapDataのStride*Height を確認してみてはいかがでしょう。 > 下記のコードで、pictureBox1が白色になるのは確認しましたが。 > > private void button1_Click(object sender, EventArgs e) > { > var scan0 = Enumerable.Repeat<byte>(0xff, (((201 * 3) + 1) * 100) ).ToArray(); > Bitmap bitmap = new Bitmap(201, 100, 204, PixelFormat.Format24bppRgb, IntPtr.Zero); > BitmapData bitmapData = bitmap.LockBits( > new Rectangle(0, 0, 201, 100), > ImageLockMode.WriteOnly, > PixelFormat.Format24bppRgb); > Marshal.Copy(scan0, 0, bitmapData.Scan0, scan0.Length); > bitmap.UnlockBits(bitmapData); > pictureBox1.Image = bitmap; > } > > 24bitBMPはパディング考慮する必要があり、画像処理する時に32bit単位で1ピクセル纏めて処理とかもしづらいので、32bitBMPの方が扱いやすいと思います。
ご回答ありがとうございます。 プログラムを編集して試してみましたがうまくいきません。 下記プログラムでImageWidth が(4の倍数)か(4の倍数-1)の時はうまく動くのですがそれ以外の時にうまく動きません。
kiku 様が教えてくれた下記サイトを見て理解したつもりですが動かない原因が分かりません。
> 下記のことを理解すると、答えがわかると思います。 > https://imagingsolution.net/program/csharp/bitmap-data-memory-format/
何が悪いのでしょうか?? よろしくお願いします。
const int ImageWidth = 100; const int ImageHeight = 50;
int stride = (ImageWidth * 24 + 31) / 32 * 4; int dataWidth = (ImageWidth + (stride / 3 - ImageWidth)) * 3;
var scan0 = Enumerable.Repeat<byte>(0x00, (dataWidth) * ImageHeight).ToArray();
// 青のグラデーションになるようなデータ作成 byte c; for (int y = 0; y < ImageHeight; y++) { c = 0; for (int x = 0; x < ImageWidth * 3; x++) { if (x % 3 == 0) { int index = y * (dataWidth) + x; scan0[index] = c; c+=2; } } } // --------------------
Bitmap bitmap = new Bitmap(ImageWidth, ImageHeight, PixelFormat.Format24bppRgb);
BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, ImageWidth, ImageHeight), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); Marshal.Copy(scan0, 0, bitmapData.Scan0, scan0.Length); bitmap.UnlockBits(bitmapData); pictureBox1.Image = bitmap;
|