tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル 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 相当の部分しか利用されないようです。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。