タイトル : Re^8: GetDIbitsの使用方法について 投稿日 : 2014/03/24(Mon) 05:04 投稿者 : 魔界の仮面弁士
> '初期化 > bmpinfo.biHeight = 80 あれ? ボトムアップ形式ではなく、トップダウン形式が必要なのですよね? なぜ、高さに正数を指定しておられるのでしょうか? http://msdn.microsoft.com/ja-jp/library/cc428673.aspx 》 高さに正の値を指定するとボトムアップのビットマップデータ(一般的なビットマップデータ)が、 》 負の値を指定するとトップダウンのビットマップデータが格納されます。 > '★bmpinfoが設定済みなので不要?コメント行にしても結果は同じでした。 > GetDIBits hMemDC, hBmp, 0, bmpinfo.biHeight, ByVal 0&, bmpinfo, 0 > '配列の宣言 > ReDim pixel(80 - 1, 80 - 1) As Long 動作上は問題ないにせよ、これだと不自然なコードにみえます。 lpvBits に NULL 参照を渡して呼び出すのは、スキャンデータに必要な領域の大きさを取得するためです。 ですから、バッファサイズ(biSizeImage)などが事前にわかっている場合には、取得処理など不要ですし、 意図して取得されているなら、後続の処理では bmpinfo に書き込まれた値を利用すべきです。 > '★★高さを−にするとビットマップが逆転する? > bmpinfo.biHeight = -bmpinfo.biHeight 現在のコードだと、80 をセットしておいてからマイナス反転させていますが、 それだと無駄なので、最初から biHeight に -80 を渡した方がスマートでしょう。 GetDIBits で高さを調べてから、走査方向を逆転させるようなコードであれば、 提示された処理手順でも良いと思いますけど。 > '★★↑次STEPにAbsで絶対値を代入しているので不要のはずなのに > 'この行が無い場合は結果が違う(無い場合、画像上下が逆) > '色を取得,Pixel配列には画像の色が入る > GetDIBits hMemDC, hBmp, 0, Abs(bmpinfo.biHeight), pixel(0, 0), bmpinfo, 0 何故、第4引数に「絶対値」を渡す必要があるのかは把握されていますか? 第 4 引数は、「走査線行の数」ですから、マイナスが入る事はありえないからです。 (だからこそ、Unsigned Integer 型のパラメータとなっているわけで) ところで、走査線行(スキャンライン)の意味はご存知でしょうか。 X 方向に並んだ一行分のラインのことです。 そもそもビットマップというものは、同じサイズの行データ(スキャンライン)を 並べたデータとして管理されています。各スキャンラインは、4の倍数サイズの単位で 確保される仕様のため、たとえば256色のビットマップの場合、幅79のBMPは、 幅80の場合と同じファイルサイズとなってしまう仕様です。 (フルカラーの場合は、1ドットごとに4バイトを消費するため、こうしたズレは生じません) そしてそのスキャンラインは、御存じのように基本的には下から積み上げていく仕様です。 80x80 サイズの画像であれば、その積み方は ( 0,79) …… (79,79) 第0ライン : : : : ( 0, 0) …… (79, 0) 第79ライン という配置になっているわけです。biHeight がマイナスの場合は、上下逆順なので、 ( 0, 0) …… (79, 0) 第79ライン : : : : ( 0,79) …… (79,79) 第0ライン という配置です。 さて、話を GetDIBits に戻しますが、これの第3引数は「走査を開始する行」であり、 第4引数は「操作する行数」を意味しています。それを踏まえて、現在の GetDIBits hMemDC, hBmp, 0, 80, … という指定を、もしも GetDIBits hMemDC, hBmp, 0, 60, … という指定にしたらどうなるでしょうか。 試してみると分かりますが、ボトムアップ形式であれば、 ( 0,79) …… (79,79) 第0ライン : : ( 0,19) …… (79,19) 第59ライン までが転送されますし、トップダウン形式であれば、 ( 0,19) …… (79,19) 第59ライン : : ( 0,79) …… (79,79) 第0ライン までが転送される結果となります。 第3引数を 0 ではなく 10 から始めれば、第10ラインからの分が転送されます。 上記の仕組みが分かれば、 > '★★↑次STEPにAbsで絶対値を代入しているので不要のはずなのに という疑問もとけるかと思います。 > Private Type BITMAPINFO この構造は BITMAPINFO ではなく、BITMAPINFOHEADER のものですよね。 http://msdn.microsoft.com/ja-jp/library/cc352308.aspx http://msdn.microsoft.com/ja-jp/library/z5731wbz.aspx 今回はフルカラー指定の為、bmiColors メンバーを使わないとはいえ、 それを BITMAPINFO の名で宣言するのは、少々奇妙な印象を受けます。 (たとえば 8 bit カラーの場合、現在の構造体定義だとメモリ破壊を引き起こします) なお、ビットマップ情報ヘッダというものは、 12 バイト (BITMAPCOREHEADER) OS/2 40 バイト (BITMAPINFOHEADER) Windows 52 バイト (BITMAPV2HEADER) 56 バイト (BITMAPV3HEADER) 64 バイト (BITMAPINFOHEADER2) OS/2 2.x 以降 108 バイト (BITMAPV4HEADER) Win95以降 124 バイト (BITMAPV5HEADER) Win98以降 のように複数のフォーマットがあるのですが、今回の利用方法では、 BITMAPV5HEADER を指定しても、BITMAPINFOHEADER 相当の部分しか利用されないようです。 |