LoadImageで読み込んだbmpの縦、横のサイズ取得方法をご教授願います。
用途はBitBltの引数にある縦、横のサイズを指定するためです。
いろいろサンプルコードを探したのですがBitBltの引数は固定値であったりピクチャボックスのサイズであったりして、ファイル読み込みした直のbmpの縦、横のサイズを取得するコードが見つかりませんでした。(ないはずはないと思って探したのですが・・・)
環境:VB6.0,win2000
------------------------------------------------
Dim dev_contxt As Long
dev_contxt = LoadImage(0, "G:\VB\テスト\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
'この後がわかりません。
-----------------------------------------------
戻り値がBITMAPINFOのHANDLEになっているから、それをVBで定義した
BITMAPINFOHEADER構造体の変数にCopyMemoryでコピーするなりして
直接WidthとHeightの値を見ればよいのでは?
参考URL
http://msdn2.microsoft.com/ja-jp/library/z5731wbz(VS.80).aspx
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/bitmapinfoheaderstructure.asp
すばやい回答ありがとうございます。
ご教授いただいた方法で試してみましたがCopyMemoryで正常な値が取得できません。(幅、高さにマイナスの値が入ってりしています)
読み込んでいるtest.bmpはペイントで作成しているため正常なデータのはずなのですが。
★BITMAPINFO型をもうひとつ用意し、[pnt]の代わりに設定してみたところCopyMemoryは動作しておりますので[pnt]に設定している値が怪しいと思っております。
誠に申し訳ございませんが[pnt]の設定方法、使い方に問題があるかご確認願えますでしょうか?
-----------------------------------------------------------
Type BITMAPINFOHEADER
biSize As Long 'ヘッダーのサイズ_
biWidth As Long '幅(ピクセル単位)
biHeight As Long '高さ(ピクセル単位)
biPlanes As Integer '常に1
biBitCount As Integer '1ピクセルあたりのカラービット数
biCompression As Long '圧縮方法
biSizeImage As Long 'ピクセルデータの全バイト数
biXPelsPerMeter As Long '0または水平解像度
biYPelsPerMeter As Long '0または垂直解像度
biClrUsed As Long '通常は0
biClrImportant As Long '通常は0
End Type
Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
' bmiColors(255) As RGBQUAD
End Type
・
・
・
Dim bmp_infoh As BITMAPINFO
Dim lngBMP As Long
Dim pnt As Long
Dim alloc_hnd As Long
lngBMP = LoadImage(0, "G:\VB\テスト\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
alloc_hnd = GlobalAlloc(0, Len(lngBMP))
pnt = GlobalLock(alloc_hnd)
CopyMemory bmp_infoh, pnt, Len(bmp_infoh)★
-----------------------------------------------------------
下記のようになるんじゃないでしょうか。
lngBMP = LoadImage(0, "G:\VB\テスト\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
' alloc_hnd = GlobalAlloc(0, Len(lngBMP)) <---これは要らないですね
' pnt = GlobalLock(alloc_hnd)
pnt = GlobalLock(lngBMP) 'ビットマップハンドルをロックして
CopyMemory bmp_infoh, pnt, Len(bmp_infoh) ’BITMAPINFOHEADERの中身をコピー
'この後、GlobalUnlockで後処理
訂正
CopyMemory bmp_infoh, pnt, Len(bmp_infoh)
↓こうした方がいいかも
CopyMemory infoh,ByVal pnt, Len(bmp_infoh)
' alloc_hnd = GlobalAlloc(0, Len(lngBMP)) <---これは要らないですね
' pnt = GlobalLock(alloc_hnd)
→変な処理になっていますが、GlobalAllocを間に挟まないとGlobalLockの戻り値のハンドルが取得できない(0になってしまう)ため上記のような処理を入れました。
MSDNのヘルプやいろんなサイトを見てみるとどうもGlobalLockの引数はGlobalXXXXといった関数の戻り値を渡してあげる必要があるようです。
追加情報です。
CopyMemory後のbmp_infohの値をデバッグで確認すると不定値(複数回確認するとそれぞれ値が異なる)になっておりました。pntのアドレスが不正なのは間違いないようです。
この観点でもう少し調べてみます。
すいません。レス漏れがありました。
>CopyMemory bmp_infoh, pnt, Len(bmp_infoh)
>↓こうした方がいいかも
>CopyMemory infoh,ByVal pnt, Len(bmp_infoh)
→変更しましたが特に変化なしでした。
#第一引数はbmp_infohで確認しています。
ほんとですね。
LoadImageで取得したビットマップハンドルをロックしようとすると
GlobalAllocがNULLを返していますね。
試さずに回答していました。
原因はちょっと思いつかないので他の有識者の回答をまってください。すみません。
ただ、ビットマップファイルの画像サイズを取得したいだけなら
以下のようなやり方でもできます。(ビットマップファイルを直接読む)
Dim hBmp As Long
Dim stBmi As BITMAPINFOHEADER
Dim lPtr As Long
Dim bytB(13) As Byte
Dim intF As Integer
intF = FreeFile
Open "ビットマップファイル名" For Binary As #intF
Get #intF, , bytB 'ファイルヘッダを読み飛ばす
Get #intF, , stBmi 'BITMAPINFOHEADERを取得
Close #intF
'サイズをプリント
Debug.Print stBmi.biWidth, stBmi.biHeight
参考URL
http://www.kk.iij4u.or.jp/~kondo/bmp/
GetObjectで取得できないでしょうか?
Option Explicit
Private Declare Function LoadImage Lib "User32.dll" Alias "LoadImageA" _
(ByVal hinst As Long, ByVal lpszName As String, ByVal uType As Long, _
ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal fuLoad As Long) As Long
Private Const IMAGE_BITMAP As Long = 0&
Private Const LR_LOADFROMFILE As Long = 16&
Private Declare Function DeleteObject Lib "Gdi32.dll" (ByVal hObject As Long) As Long
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Declare Function GetObject Lib "Gdi32.dll" Alias "GetObjectA" _
(ByVal hgdiobj As Long, ByVal cbBuffer As Long, ByRef lpvObject As BITMAP) As Long
Public Sub Test()
Dim hBitmap As Long
Dim bmp As BITMAP
hBitmap = LoadImage(0&, "G:\VB\テスト\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
If hBitmap <> 0 Then
If GetObject(hBitmap, LenB(bmp), bmp) <> 0 Then
MsgBox "高さ:" & bmp.bmHeight & vbCrLf & "横幅:" & bmp.bmWidth
End If
DeleteObject hBitmap
End If
End Sub
>戻り値がBITMAPINFOのHANDLEになっているから
これはどこの情報でしょうか?
ちなみに、LoadImageではなく、VBのLoadPictureを使えば、
PictureオブジェクトのWidth/HeightプロパティからHiMetric単位の値が取れます。
過去ログ:http://madia.world.coocan.jp/vb/vb_bbs/200501_05010008.html
ピクセル単位に変換するには
http://www.geocities.co.jp/SiliconValley/4334/unibon/asp/getimagesize.html
を参考にしてください。
Blueさん、てふさん>
ご回答ありがとうございます。
GetObjectで取得できましたので解決とさせていただきます。
親切にご回答いただきありがとうございました。
ツイート | ![]() |