2

私はCシャープ、.net 4(重要な場合はクライアントプロファイル)をbyte使用しており、画像の生データを含む配列を持っています。具体的には、この画像:

良いイメージ

これは SANE テスト バックエンドからの出力であり、フォーマットは SANE の Web サイトで詳しく説明されています。ちなみに、私はパラメータを渡しました:

  • 深さ: 8
  • モード: 色

そしてそれは戻ってきました:

  • フォーマット: RGB
  • 深さ: 8
  • 行: 196
  • ラインあたりのピクセル: 157
  • 1 行あたりのバイト数: 471
  • 長さが 92316 バイトのバイト ストリーム

したがって、数値は妥当なようです (196 * (157 * 471) = 92316) - 1 ピクセルあたり 3 バイト (24 ビット)。

SANE のドキュメントを読むと、データは左上隅から左から右、上から下にピクセルあたり 3 バイトの順序で並べられます。

red,green,blue   red,green,blue  
--------------   --------------
    byte 1           byte 2       ...

私は画像についてよく知っているので、それをビットマップにロードするのは非常に簡単だと思い、これをノックアップしました:

var bmp = new Bitmap(157, 196, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp
    .LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
              ImageLockMode.ReadWrite,
              bmp.PixelFormat);
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
bmp.UnlockBits(bmpData);

しかし、それはこれを生み出しました:

悪いイメージ

近いですが、いわば葉巻はありません。

それで、私は何を間違えましたか?

4

2 に答える 2

4

問題は、ビットマップでは、行のバイトと次の行のバイトの間にギャップがあることです (詳細はこちら)。速度が主な関心事でない場合は、 SetPixelとループを使用すると、これをはるかに簡単に行うことができます。

編集:
これにより、SetPixel と比較して大幅な速度向上が得られますが、残念ながらループを使用する必要があります;)

for(int i = 0; i < bmp.Height; i++) {
    Marshal.Copy(data, 
        i * bmp.Height,
        bmpData.Scan0 + i * bmpData.Stride,
        bmp.Width * 3);
}

コードをテストしていないことに注意してください。しかし、アイデアを得るには十分なはずです。

于 2013-03-06T18:23:02.670 に答える
3

ビットマップでは、行を特定のサイズ (4 バイト、検索形式の詳細はこちら)にパディングする必要があります。

その結果、1 行あたり 157 ピクセルがビットマップのビットのバイナリ形式に正確にマップされず、次の各行が少しシフトされます。行ごとに158 * 3バイトを割り当て、各行をソース(パディングがないため正確にはビットマップではない)形式から宛先にコピーし、各行の最後の3バイトを0で埋める必要があると思います。

于 2013-03-06T18:24:27.420 に答える