C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 >>
■100272  カラービットマップの描画について
□投稿者/ まさお -(2022/07/14(Thu) 14:27:54)

    分類:[C#] 

    幅が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); // ここでエラー

    どこが悪いのかご存知のかいらっしゃいませんか?
    よろしくお願いします。



親記事 /過去ログ174より / 関連記事表示
削除チェック/

■100273  Re[1]: カラービットマップの描画について
□投稿者/ radian -(2022/07/14(Thu) 15:27:56)
    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(); //+1はパディング(横一行バイト数を4の倍数にする)
    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の方が扱いやすいと思います。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100284  Re[2]: カラービットマップの描画について
□投稿者/ まさお -(2022/07/15(Fri) 10:28:44)
    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;



記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100297  Re[3]: カラービットマップの描画について
□投稿者/ KOZ -(2022/07/15(Fri) 11:42:15)
    No100284 (まさお さん) に返信
    > プログラムを編集して試してみましたがうまくいきません。
    > 下記プログラムでImageWidth が(4の倍数)か(4の倍数-1)の時はうまく動くのですがそれ以外の時にうまく動きません。
    
    「うまく動きません」の内容が変わってます。
    2箇所修正したら動きました。dataWidth って不要なのでは?
    
    protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);
    
        int left = 10;
    
        for (int i = 0; i < 4; i++) {
            int ImageWidth = 100 + i;
            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(); ★ここ
            var scan0 = Enumerable.Repeat<byte>(0x00, stride * 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;  ★ここ
                        int index = y * (stride) + x;
                        scan0[index] = c;
                        c += 2;
                    }
                }
            }
    
            using (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);
                e.Graphics.DrawImage(bitmap, new Point(left, 10));
            }
            left += ImageWidth + 10;
        }
    }
    
    
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100300  Re[4]: カラービットマップの描画について
□投稿者/ radian -(2022/07/15(Fri) 11:46:27)
    代理デバッグは本人の為にならないからやめた方がいいっすよ。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100302  Re[5]: カラービットマップの描画について
□投稿者/ KOZ -(2022/07/15(Fri) 12:26:02)
    No100300 (radian さん) に返信
    > 代理デバッグは本人の為にならないからやめた方がいいっすよ。

    場合によりますね。
    デバッグすればすぐわかるようなときならしませんが、これはデバッグしたところでわかりにくい問題かと。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100303  Re[6]: カラービットマップの描画について
□投稿者/ radian -(2022/07/15(Fri) 12:34:49)
    2022/07/15(Fri) 12:37:52 編集(投稿者)

    No100302 (KOZ さん) に返信
    > ■No100300 (radian さん) に返信
    >>代理デバッグは本人の為にならないからやめた方がいいっすよ。
    >
    > 場合によりますね。
    > デバッグすればすぐわかるようなときならしませんが、これはデバッグしたところでわかりにくい問題かと。

    いやdataWidthの値見たらすぐ判るでしょ…
    気付けるように色々ヒントも書いてる。
    もうほぼ自力で正解辿り着けそうなとこまできてるんだから
    そこは答え書くべきじゃない。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100304  Re[7]: カラービットマップの描画について
□投稿者/ KOZ -(2022/07/15(Fri) 12:53:29)
    No100303 (radian さん) に返信
    > いやdataWidthの値見たらすぐ判るでしょ…
    > 気付けるように色々ヒントも書いてる。
    > もうほぼ自力で正解辿り着けそうなとこまできてるんだから
    > そこは答え書くべきじゃない。

    「それってあなたの感想でしょ」ってやつですね。
    間違った内容を書いてるならともかく、レスのつけ方まで文句をいわれるすじあいはありません。
    不毛なのでやめときましょう。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100305  Re[8]: カラービットマップの描画について
□投稿者/ radian -(2022/07/15(Fri) 13:04:06)
    2022/07/15(Fri) 13:24:58 編集(投稿者)

    No100304 (KOZ さん) に返信
    > ■No100303 (radian さん) に返信
    >>いやdataWidthの値見たらすぐ判るでしょ…
    >>気付けるように色々ヒントも書いてる。
    >>もうほぼ自力で正解辿り着けそうなとこまできてるんだから
    >>そこは答え書くべきじゃない。
    >
    > 「それってあなたの感想でしょ」ってやつですね。
    > 間違った内容を書いてるならともかく、レスのつけ方まで文句をいわれるすじあいはありません。
    > 不毛なのでやめときましょう。

    本人がデバッグ方法を身に付けるってのが重要な訳で、
    あなたは答え貼り付けて自己満足するだけでいいと思うけど、
    それによって、デバッグ方法を身に付ける機会を奪ってるって事だけは理解してください。
    単なる計算ミスで、再度同じような質問をしないように気付きを与えたいのです。

    それでも、うるせぇな質問相手の事は知ったこっちゃないし
    自分は答えそのまま貼りつけたいんだよ!というなら、
    もはや特に何も言う事はありませんが。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100306  Re[9]: カラービットマップの描画について
□投稿者/ kiku -(2022/07/15(Fri) 13:13:47)
    radianさん
    KOZさん

    私見ですが、どちらも正しいと思います。
    どちらを要望されているかは質問者さんしかわかりません。
    質問者さんの応答を待ちましょう。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100307  Re[10]: カラービットマップの描画について
□投稿者/ radian -(2022/07/15(Fri) 13:17:01)
    No100306 (kiku さん) に返信
    > radianさん
    > KOZさん
    >
    > 私見ですが、どちらも正しいと思います。
    > どちらを要望されているかは質問者さんしかわかりません。
    > 質問者さんの応答を待ちましょう。

    そうですね、ちょっと熱くなりすぎました。
    失礼しました。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100274  Re[1]: カラービットマップの描画について
□投稿者/ kiku -(2022/07/14(Thu) 15:37:42)
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100288  Re[2]: カラービットマップの描画について
□投稿者/ radian -(2022/07/15(Fri) 11:13:57)
    2022/07/15(Fri) 11:26:08 編集(投稿者)

    もう一度書きますね。

    『とりあえずデバッグして scan0.Lengthと、bitmapDataのStride*Height を確認してみてはいかがでしょう。』

    単なる計算ミスだと思います。
    デバッグの仕方が判らないなら、まずデバッグの仕方を学習してください。
    https://docs.microsoft.com/ja-jp/visualstudio/debugger/debugging-absolute-beginners?view=vs-2022&tabs=csharp

    あと、うまくいきませんという言葉は使わず、具体的に相手に伝わるように書く努力をしてください。
    第三者には何のこっちゃ判らないです。
    あなたは、病院で医者に病気の症状伝えるときに、なんか調子悪いですとしか言わないんですか?
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100291  Re[3]: カラービットマップの描画について
□投稿者/ まさお -(2022/07/15(Fri) 11:28:22)
    No100288 (radian さん) に返信
    > もう一度書きますね。
    >
    > 『とりあえずデバッグして scan0.Lengthと、bitmapDataのStride*Height を確認してみてはいかがでしょう。』
    >
    > 単なる計算ミスだと思います。
    > デバッグの仕方が判らないなら、まずデバッグの仕方を学習してください。
    > https://docs.microsoft.com/ja-jp/visualstudio/debugger/debugging-absolute-beginners?view=vs-2022&tabs=csharp

    すいません。
    色々試していて間違ったコードのまま貼り付けてしまいました。
    (誤)var scan0 = Enumerable.Repeat<byte>(0x00, (dataWidth) * ImageHeight).ToArray();
    の部分は
    (正)var scan0 = Enumerable.Repeat<byte>(0x00, stride * ImageHeight).ToArray();

    となっておりscan0.Lengthと、bitmapDataのStride*Heightが同じ値になっているのは確認済みです。
    ImageWidth が(4の倍数)か(4の倍数-1)のときは期待するように青のグラデーションが表示されるのですが
    それ以外の時におかしな表示になってしまうのです…
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100292  Re[4]: カラービットマップの描画について
□投稿者/ radian -(2022/07/15(Fri) 11:30:07)
    2022/07/15(Fri) 11:33:06 編集(投稿者)

    No100291 (まさお さん) に返信
    > (正)var scan0 = Enumerable.Repeat<byte>(0x00, stride * ImageHeight).ToArray();

    ちなみに、初期値セットしたいからEnumerable.Repeat使っただけなので、
    初期値0でいいなら単純に new byte[確保サイズ] でいいです。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100295  Re[4]: カラービットマップの描画について
□投稿者/ kiku -(2022/07/15(Fri) 11:38:14)
    No100291 (まさお さん) に返信
    > ■No100288 (radian さん) に返信
    > となっておりscan0.Lengthと、bitmapDataのStride*Heightが同じ値になっているのは確認済みです。
    > ImageWidth が(4の倍数)か(4の倍数-1)のときは期待するように青のグラデーションが表示されるのですが
    > それ以外の時におかしな表示になってしまうのです…

    現在の最新のソースはどのようになっているのでしょうか?
    一番最初に提示されたソースは、scan0が定義されていないので
    なんともコメントの付けようがなかったです。
    最小のソースで、動作する最新のソースの開示が必要かと思います。
    そうすると、いろいろな人からコメントが付く可能性が高まると思います。
記事No.100272 のレス /過去ログ174より / 関連記事表示
削除チェック/

■100320  Re[5]: カラービットマップの描画について
□投稿者/ まさお -(2022/07/15(Fri) 18:34:56)
    解決しました!
    やはりご指摘の通りケアレスミスでした。
    そもそもの考え方が間違っていると思い込み計算等の確認がおろそかになってしまったようです。

    ご回答いただいたみなさんありがとうございました。
記事No.100272 のレス / END /過去ログ174より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -