by 淡幻星 » 2006年3月19日(日) 14:37
レスが大変遅れてしまい申し訳ありません。
やっとデバグする時間が取れました。
≫ノッチ様
動作確認ありがとうございます。
当方でも、1階層目の関数呼び出しでは正常動作しました。
しかし、関数から関数を呼び出し・・・というように2階層以上の
関数呼び出しにおいて、エラーにこそならないものの、
値が代入されなかったり、関数の途中で勝手に抜けたりと、
やはりコードの動作がおかしいようです。
(Ver.3.13, Ver.4.10.02, Ver.4.23.00 にて確認。)
もっとも、DLLを使わずに済むのであればそちらのほうが都合よいので、
hira様のコードで対処しようかと思っています。
≫hira様
PNGヘッダからの画像サイズの読み取りコードも示していただき、
ありがとうございます。
それを踏まえて、画像(Bmp,Gif,Jpeg,Png)の縦横サイズ読み取り&
ビットマップハンドル(Pngを除く)取得をクラスにまとめてみたのですが、
get_Handle() が失敗するようです(返り値がFALSE)。
IPictureインターフェースに関してはさっぱり分からないので、
お手上げ状態なのですが、こちらエラーの原因などわかりますでしょうか?
クラスReadPics定義はこちらをクリック。 [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Declare Function CreateStreamOnHGlobal Lib "ole32" (hGlobal As HGLOBAL,fDeleteOnRelease As DWord,ppstm As VoidPtr) As DWord
Declare Function OleLoadPicture Lib "olepro32" (pStream As LPSTREAM,lSize As Long,fRunmode As DWord,riid As *GUID,ppvObj As VoidPtr) As DWord
Declare Sub AtlHiMetricToPixel Lib "atl" (lpSizeInHiMetric As *SIZE,lpSizeInPix As *SIZE)
'{7BF80980-BF32-101A-8BBB-00AA00300CAB}
Class IPicture
Inherits IUnknown
Public
Virtual Function get_Handle(pHandle As *HANDLE) As DWord
Virtual Function get_hPal(phPal As *HANDLE) As DWord
Virtual Function get_Type(pType As WordPtr) As DWord
Virtual Function get_Width(pWidth As DWordPtr) As DWord
Virtual Function get_Height(pHeight As DWordPtr) As DWord
Virtual Function Render(hDC As HDC,x As Long,y As Long,cx As Long,cy As Long,xSrc As Long,ySrc As Long,cxSrc As Long,cySrc As Long,pRcWBounds As *RECT) As DWord
Virtual Function set_hPal(hPal As HANDLE) As DWord
Virtual Function get_CurDC(phDC As *HDC) As DWord
Virtual Function SelectPicture(hDCIn As HDC,phDCOut As *HDC,phBmpOut As *HANDLE) As DWord
Virtual Function get_KeepOriginalFormat(pKeep As DWordPtr) As DWord
Virtual Function put_KeepOriginalFormat(keep As DWord) As DWord
Virtual Function PictureChanged() As DWord
Virtual Function SaveAsFile(pStream As LPSTREAM,fSaveMemCopy As DWord,pCbSize As DWordPtr) As DWord
Virtual Function get_Attributes(pDwAttr As DWordPtr) As DWord
End Class
TypeDef LPPICTURE=*IPicture
Const PICTYPE_UNINITIALIZED = -1
Const PICTYPE_NONE = 0
Const PICTYPE_BITMAP = 1
Const PICTYPE_METAFILE = 2
Const PICTYPE_ICON = 3
'Pngの縦横サイズを読むための演算マクロ(たぶん)。
Const BigEndianToLittleEndian(Num)=(((Num) And &HFF)<<24 Or ((Num) And &HFF00)<<8 Or ((Num) And &HFF0000)>>8 Or ((Num) And &HFF000000)>>24)
'Jpeg,Gif(,Bmp)のビットマップハンドル読み込みと縦横サイズ取得
' +Pngの縦横サイズ取得を行うクラス。
Class ReadPics
udtPicPixel As SIZE
hPicRP As HBITMAP
'ファイル内容がPngかどうかを返す
Function IsPng( hFile As HANDLE ) As Long
Dim pAnyBuf[8] As Byte
Dim dwReadSize As Dword
ReadFile( hFile, pAnyBuf, 8, VarPtr(dwReadSize), ByVal NULL )
If( (pAnyBuf[0]=&H89) _
And(pAnyBuf[1]=&H50) _
And(pAnyBuf[2]=&H4E) _
And(pAnyBuf[3]=&H47) _
And(pAnyBuf[4]=&H0D) _
And(pAnyBuf[5]=&H0A) _
And(pAnyBuf[6]=&H1A) _
And(pAnyBuf[7]=&H0A) )Then
IsPng = TRUE
Else
IsPng = FALSE
EndIf
EndFunction
'Pngファイルの縦横サイズを読み取る
Function GetPngSizeWH( hFile As HANDLE ) As Long
Dim dwWidth As DWord
Dim dwHeight As DWord
DIm dwReadSize As DWord
SetFilePointer( hFile, 16, NULL, FILE_BEGIN )
ReadFile( hFile, VarPtr(dwWidth), 4, VarPtr(dwReadSize), ByVal NULL )
ReadFile( hFile, VarPtr(dwHeight), 4,VarPtr(dwReadSize), ByVal NULL )
dwWidth = BigEndianToLittleEndian( dwWidth )
dwHeight = BigEndianToLittleEndian( dwHeight )
udtPicPixel.cx = dwWidth
udtPicPixel.cy = dwHeight
EndFunction
Public
Sub ReadPics()
hPicRP = NULL
EndSub
Sub ~ReadPics()
If( hPicRP<>NULL )Then
DeleteObject( hPicRP )
EndIf
EndSub
'指定された画像ファイルの縦横サイズとビットマップハンドル(Png以外)を得る。
Function CreatePic( pPicPath As BytePtr ) As Long
Dim hFile As HANDLE
Dim hGlobal As HGLOBAL
Dim pGlobal As VoidPtr
Dim dwSize As DWord
Dim dwReadSize As DWord
Dim IID_IPicture=[&H7BF80980,&HBF32,&H101A,[&H8B,&HBB,&H00,&HAA,&H00,&H30,&H0C,&HAB]] As GUID
Dim lpStream As LPSTREAM
Dim lpPicture As LPPICTURE
Dim iWidth As Long,iHeight As Long
Dim udtHiMetric As SIZE
Dim hOle=NULL As HANDLE
Dim wType As Word
'ファイルオープン
hFile = CreateFile( pPicPath, GENERIC_READ, NULL, ByVal NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )
If( hFile=INVALID_HANDLE_VALUE )Then
CreatePic = FALSE
ExitFunction
EndIf
If( IsPng( hFile )=TRUE )Then
'Pngファイルは別途処理
CreatePic = GetPngSizeWH( hFile )
CloseHandle( hFile )
If( hPicRP<>NULL )Then
DeleteObject( hPicRP )
EndIf
hPicRP = NULL
ExitFunction
EndIf
dwSize = GetFileSize( hFile, NULL )
hGlobal = GlobalAlloc( GPTR, dwSize )
pGlobal = GlobalLock( hGlobal )
ReadFile( hFile, pGlobal, dwSize, VarPtr(dwReadSize), ByVal NULL )
GlobalUnlock( hGlobal )
CloseHandle( hFile )
/* オーパーツ扱い(笑)
OleLoadPicture()+IStrem&IPictureインターフェースを利用して
Jpeg,Gif,Bmpを読み込む。
OLE (Object Linking and Embedding)を利用しているみたい。
クリップボードのヤツ?
上記IPictureクラスにて定義? */
CreateStreamOnHGlobal( hGlobal, TRUE, VarPtr(lpStream) )
OleLoadPicture( lpStream, dwSize, TRUE, VarPtr(IID_IPicture), VarPtr(lpPicture) )
lpStream->Release()
'縦横サイズとビットマップハンドルを得る。
If( lpPicture )Then
lpPicture->get_Type( VarPtr(wType) )
If( wType<>PICTYPE_BITMAP )Then
'絵でないものは弾く
CreatePic = FALSE
Else
CreatePic = TRUE
'縦横サイズ
lpPicture->get_Width( VarPtr(iWidth) )
lpPicture->get_Height( VarPtr(iHeight) )
With udtHiMetric
.cx = iWidth
.cy = iHeight
End With
AtlHiMetricToPixel( VarPtr(udtHiMetric), VarPtr(udtPicPixel) )
'ビットマップハンドル
Dim r As Long 'デバグ用
debug
r = lpPicture->get_Handle( VarPtr(hOle) )
If( hPicRP<>NULL )Then
DeleteObject( hPicRP )
EndIf
hPicRP = hOle As HBITMAP
'開放処理
lpPicture->Release()
EndIf
Else
CreatePic = FALSE
EndIf
EndFunction
'横サイズを返す
Function GetWidth() As Long
GetWidth = udtPicPixel.cx
End Function
'縦サイズを返す
Function GetHeight() As Long
GetHeight = udtPicPixel.cy
End Function
'ビットマップハンドルを返す。
Function GetBmpHandle() As HBITMAP
GetBmpHandle = hPicRP
End Function
End Class
上記クラスの動作テストが下記
コード: 全て選択
#N88BASIC
Dim lp As ReadPics
Dim s As String
Dim hPic As HBITMAP
s = "test.jpg"
lp.CreatePic( StrPtr(s) )
Print lp.GetHeight()
Print lp.GetWidth()
hPic = lp.GetBmpHandle()
Debug '←hPicが「利用できない」になっている。
Input s
End
Ver.4.23.00にて確認。
よろしくお願いいたします。
レスが大変遅れてしまい申し訳ありません。
やっとデバグする時間が取れました。
[b]≫ノッチ様[/b]
動作確認ありがとうございます。
当方でも、1階層目の関数呼び出しでは正常動作しました。
しかし、関数から関数を呼び出し・・・というように2階層以上の
関数呼び出しにおいて、エラーにこそならないものの、
値が代入されなかったり、関数の途中で勝手に抜けたりと、
やはりコードの動作がおかしいようです。
(Ver.3.13, Ver.4.10.02, Ver.4.23.00 にて確認。)
もっとも、DLLを使わずに済むのであればそちらのほうが都合よいので、
hira様のコードで対処しようかと思っています。
[b]≫hira様[/b]
PNGヘッダからの画像サイズの読み取りコードも示していただき、
ありがとうございます。
それを踏まえて、画像(Bmp,Gif,Jpeg,Png)の縦横サイズ読み取り&
ビットマップハンドル(Pngを除く)取得をクラスにまとめてみたのですが、
get_Handle() が失敗するようです(返り値がFALSE)。
IPictureインターフェースに関してはさっぱり分からないので、
お手上げ状態なのですが、こちらエラーの原因などわかりますでしょうか?
[hide=クラスReadPics定義はこちらをクリック。][code]Declare Function CreateStreamOnHGlobal Lib "ole32" (hGlobal As HGLOBAL,fDeleteOnRelease As DWord,ppstm As VoidPtr) As DWord
Declare Function OleLoadPicture Lib "olepro32" (pStream As LPSTREAM,lSize As Long,fRunmode As DWord,riid As *GUID,ppvObj As VoidPtr) As DWord
Declare Sub AtlHiMetricToPixel Lib "atl" (lpSizeInHiMetric As *SIZE,lpSizeInPix As *SIZE)
'{7BF80980-BF32-101A-8BBB-00AA00300CAB}
Class IPicture
Inherits IUnknown
Public
Virtual Function get_Handle(pHandle As *HANDLE) As DWord
Virtual Function get_hPal(phPal As *HANDLE) As DWord
Virtual Function get_Type(pType As WordPtr) As DWord
Virtual Function get_Width(pWidth As DWordPtr) As DWord
Virtual Function get_Height(pHeight As DWordPtr) As DWord
Virtual Function Render(hDC As HDC,x As Long,y As Long,cx As Long,cy As Long,xSrc As Long,ySrc As Long,cxSrc As Long,cySrc As Long,pRcWBounds As *RECT) As DWord
Virtual Function set_hPal(hPal As HANDLE) As DWord
Virtual Function get_CurDC(phDC As *HDC) As DWord
Virtual Function SelectPicture(hDCIn As HDC,phDCOut As *HDC,phBmpOut As *HANDLE) As DWord
Virtual Function get_KeepOriginalFormat(pKeep As DWordPtr) As DWord
Virtual Function put_KeepOriginalFormat(keep As DWord) As DWord
Virtual Function PictureChanged() As DWord
Virtual Function SaveAsFile(pStream As LPSTREAM,fSaveMemCopy As DWord,pCbSize As DWordPtr) As DWord
Virtual Function get_Attributes(pDwAttr As DWordPtr) As DWord
End Class
TypeDef LPPICTURE=*IPicture
Const PICTYPE_UNINITIALIZED = -1
Const PICTYPE_NONE = 0
Const PICTYPE_BITMAP = 1
Const PICTYPE_METAFILE = 2
Const PICTYPE_ICON = 3
'Pngの縦横サイズを読むための演算マクロ(たぶん)。
Const BigEndianToLittleEndian(Num)=(((Num) And &HFF)<<24 Or ((Num) And &HFF00)<<8 Or ((Num) And &HFF0000)>>8 Or ((Num) And &HFF000000)>>24)
'Jpeg,Gif(,Bmp)のビットマップハンドル読み込みと縦横サイズ取得
' +Pngの縦横サイズ取得を行うクラス。
Class ReadPics
udtPicPixel As SIZE
hPicRP As HBITMAP
'ファイル内容がPngかどうかを返す
Function IsPng( hFile As HANDLE ) As Long
Dim pAnyBuf[8] As Byte
Dim dwReadSize As Dword
ReadFile( hFile, pAnyBuf, 8, VarPtr(dwReadSize), ByVal NULL )
If( (pAnyBuf[0]=&H89) _
And(pAnyBuf[1]=&H50) _
And(pAnyBuf[2]=&H4E) _
And(pAnyBuf[3]=&H47) _
And(pAnyBuf[4]=&H0D) _
And(pAnyBuf[5]=&H0A) _
And(pAnyBuf[6]=&H1A) _
And(pAnyBuf[7]=&H0A) )Then
IsPng = TRUE
Else
IsPng = FALSE
EndIf
EndFunction
'Pngファイルの縦横サイズを読み取る
Function GetPngSizeWH( hFile As HANDLE ) As Long
Dim dwWidth As DWord
Dim dwHeight As DWord
DIm dwReadSize As DWord
SetFilePointer( hFile, 16, NULL, FILE_BEGIN )
ReadFile( hFile, VarPtr(dwWidth), 4, VarPtr(dwReadSize), ByVal NULL )
ReadFile( hFile, VarPtr(dwHeight), 4,VarPtr(dwReadSize), ByVal NULL )
dwWidth = BigEndianToLittleEndian( dwWidth )
dwHeight = BigEndianToLittleEndian( dwHeight )
udtPicPixel.cx = dwWidth
udtPicPixel.cy = dwHeight
EndFunction
Public
Sub ReadPics()
hPicRP = NULL
EndSub
Sub ~ReadPics()
If( hPicRP<>NULL )Then
DeleteObject( hPicRP )
EndIf
EndSub
'指定された画像ファイルの縦横サイズとビットマップハンドル(Png以外)を得る。
Function CreatePic( pPicPath As BytePtr ) As Long
Dim hFile As HANDLE
Dim hGlobal As HGLOBAL
Dim pGlobal As VoidPtr
Dim dwSize As DWord
Dim dwReadSize As DWord
Dim IID_IPicture=[&H7BF80980,&HBF32,&H101A,[&H8B,&HBB,&H00,&HAA,&H00,&H30,&H0C,&HAB]] As GUID
Dim lpStream As LPSTREAM
Dim lpPicture As LPPICTURE
Dim iWidth As Long,iHeight As Long
Dim udtHiMetric As SIZE
Dim hOle=NULL As HANDLE
Dim wType As Word
'ファイルオープン
hFile = CreateFile( pPicPath, GENERIC_READ, NULL, ByVal NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )
If( hFile=INVALID_HANDLE_VALUE )Then
CreatePic = FALSE
ExitFunction
EndIf
If( IsPng( hFile )=TRUE )Then
'Pngファイルは別途処理
CreatePic = GetPngSizeWH( hFile )
CloseHandle( hFile )
If( hPicRP<>NULL )Then
DeleteObject( hPicRP )
EndIf
hPicRP = NULL
ExitFunction
EndIf
dwSize = GetFileSize( hFile, NULL )
hGlobal = GlobalAlloc( GPTR, dwSize )
pGlobal = GlobalLock( hGlobal )
ReadFile( hFile, pGlobal, dwSize, VarPtr(dwReadSize), ByVal NULL )
GlobalUnlock( hGlobal )
CloseHandle( hFile )
/* オーパーツ扱い(笑)
OleLoadPicture()+IStrem&IPictureインターフェースを利用して
Jpeg,Gif,Bmpを読み込む。
OLE (Object Linking and Embedding)を利用しているみたい。
クリップボードのヤツ?
上記IPictureクラスにて定義? */
CreateStreamOnHGlobal( hGlobal, TRUE, VarPtr(lpStream) )
OleLoadPicture( lpStream, dwSize, TRUE, VarPtr(IID_IPicture), VarPtr(lpPicture) )
lpStream->Release()
'縦横サイズとビットマップハンドルを得る。
If( lpPicture )Then
lpPicture->get_Type( VarPtr(wType) )
If( wType<>PICTYPE_BITMAP )Then
'絵でないものは弾く
CreatePic = FALSE
Else
CreatePic = TRUE
'縦横サイズ
lpPicture->get_Width( VarPtr(iWidth) )
lpPicture->get_Height( VarPtr(iHeight) )
With udtHiMetric
.cx = iWidth
.cy = iHeight
End With
AtlHiMetricToPixel( VarPtr(udtHiMetric), VarPtr(udtPicPixel) )
'ビットマップハンドル
Dim r As Long 'デバグ用
debug
r = lpPicture->get_Handle( VarPtr(hOle) )
If( hPicRP<>NULL )Then
DeleteObject( hPicRP )
EndIf
hPicRP = hOle As HBITMAP
'開放処理
lpPicture->Release()
EndIf
Else
CreatePic = FALSE
EndIf
EndFunction
'横サイズを返す
Function GetWidth() As Long
GetWidth = udtPicPixel.cx
End Function
'縦サイズを返す
Function GetHeight() As Long
GetHeight = udtPicPixel.cy
End Function
'ビットマップハンドルを返す。
Function GetBmpHandle() As HBITMAP
GetBmpHandle = hPicRP
End Function
End Class[/code][/hide]
上記クラスの動作テストが下記
[code]#N88BASIC
Dim lp As ReadPics
Dim s As String
Dim hPic As HBITMAP
s = "test.jpg"
lp.CreatePic( StrPtr(s) )
Print lp.GetHeight()
Print lp.GetWidth()
hPic = lp.GetBmpHandle()
Debug '←hPicが「利用できない」になっている。
Input s
End[/code]
Ver.4.23.00にて確認。
よろしくお願いいたします。