DIBノメモリハンドルについて

解決


だい  2004-07-15 12:32:37  No: 84590  IP: [192.*.*.*]

いつもお世話になっています。
VB6、W2Kの開発環境なのですが、
市販の画像関連OCXを使用して作業を行っています。
そのOCXに表示されている画像のDIBメモリハンドルを取得するメソッドがあり、
取得したDIBメモリハンドルからPICTURBOXに画像をLOADしたいのですが
方法がわかりません。
取得できるのはDIBのメモリハンドルのみなので、画像のサイズ等も
取得したハンドルを解決してBITMAPINFO等の中身を参照しないと
解らないのですが、ハンドルからBITMAPINFOを参照する方法も
解りません。
WindowsAPI等もいろいろ調べたのですが
画像関連は初心者なものでよくわかりません。

どうか、みなさんのお力を御貸し頂けないでしょうか?
よろしくお願いします。

編集 削除
たこす  2004-07-16 12:01:54  No: 84591  IP: [192.*.*.*]

回答が無い様なので、思い込みで書きます。
グローバルメモリオブジェクトのハンドルなら、GlobalLockで、メモリブ
ロックの先頭へのポインタが得られると思います。
それから、RtlMoveMemoryでBITMAPINFO構造体やイメージビットの情報を
取得すれば、PictureBoxのDCに描画できると思います。

編集 削除
だい2  2004-07-16 15:25:44  No: 84592  IP: [192.*.*.*]

たこすさんありがとうございます。
おっしゃるとうり、MoveMemoryでBitmapInfoHeaderは
構造体が決まっているので取れるのですが、
ピクセル情報は、バイト数がBitmapInfoHeaderを参照しないと
決まらないので、動的配列にするしかなく、
動的配列にするとMoveMemoryでまとめてコピーできません。

現状ではむりやり(先に進むために)ピクセル情報のポインタ
を算出(単純にバイト数を加算)してSetdibtstodeviceを
発行していますが、PictuerBoxは真っ黒けです。
BitCountが1の白黒のBitmapだからなのでしょうか?

編集 削除
たこす  2004-07-16 20:24:33  No: 84593  IP: [192.*.*.*]

> 動的配列にするとMoveMemoryでまとめてコピーできません。
動的なバイト配列にまとめてコピーできませんか?

あとは、コードを見せてもらわないと、はっきりしませんね。

編集 削除
たこす  2004-07-16 21:58:31  No: 84594  IP: [192.*.*.*]

> ピクセル情報は、バイト数がBitmapInfoHeaderを参照しないと
> 決まらないので、動的配列にするしかなく、

ピクセル情報は、バイト配列を使用せずに、
素直に、ピクセル情報の先頭アドレスを渡せばいいかも。

編集 削除
だい2  2004-07-20 11:54:36  No: 84595  IP: [192.*.*.*]

たこすさんアドバイスありがとうございます。

いろいろ試した結果、ようやくできました。
DIBが白黒で1ピクセル1ビットだったので
MoveMemoryの際に指定するデータ長がおかしかったです。

下記のようなコードでできました。

Type BITMAPP
  AA_INFO As BITMAPINFOHEADER
  AA_MAP(1) As RGBQUAD
End Type
Sub BITMAP_RTN2()

Dim R As Long, r2 As Long, R3 As Long, PNT As Long
Dim rtn As Boolean

Dim MST_AA As BITMAPP

Dim bitmap_h As BITMAPINFOHEADER
Dim PIC() As Byte
'**DIBのハンドル取得(市販OCXのメソッド)
R = Main.MdTOcr1.GetImageHandle()
PNT = GlobalLock(R)
'**BITMAPINFOへコピー
MoveMemory MST_AA, PNT, Len(MST_AA)
'**Picturboxの高さと幅を設定
Main.Picture2.Height = MST_AA.AA_INFO.biHeight * Screen.TwipsPerPixelX
Main.Picture2.Width = MST_AA.AA_INFO.biWidth * Screen.TwipsPerPixelY
'**ピクセルデータの取得エリアの再定義
ReDim PIC(MST_AA.AA_INFO.biWidth * MST_AA.AA_INFO.biHeight)

'**ピクセルデータの取得(1ピクセル1ビットで表現しているので8(1byteは8Bit)で割る
MoveMemory PIC(0), PNT + 48, CLng((MST_AA.AA_INFO.biWidth * MST_AA.AA_INFO.biHeight) / 8)

'**PICTURBOXに表示
R3 = SetDIBitsToDevice(Main.Picture2.hdc, 0, 0, _
     MST_AA.AA_INFO.biWidth, MST_AA.AA_INFO.biHeight, _
     0, 0, 0, MST_AA.AA_INFO.biHeight, _
     PIC(0), MST_AA, 0)
'**ポインタの開放
GlobalUnlock (R)
'**JPEGに出力(PicturBoxをJPEGにする
R = BMPtoJPG(App.Path & "\AAA.JPG", 90, False)

End Sub

PIC(0)の渡し方をByvalにすれば、ポインタで渡しても
OKだとおもいます。

いろいろと、ありがとうございました。

編集 削除