gto250 发表于 2011-8-15 20:59:08

如何通过图片文件的句柄获得图片的二进制数据【已解决】

本帖最后由 gto250 于 2011-8-20 06:53 编辑

#include <ScreenCapture.au3>

$HBITMAP=_ScreenCapture_Capture() ;获得截图的句柄

$file_name=@ScriptDir & "\001.bmp"
_ScreenCapture_SaveImage ($file_name, $HBITMAP);图像保存为001.bmp
$f_h=FileOpen($file_name,16);二进制模式读取文件
$str=StringTrimLeft(FileRead($f_h),2) ;去除0X
FileClose($f_h)


如何才能直接通过$HBITMAP这个图像句柄,直接得到和$str相同的数据?

lpxx 发表于 2011-8-15 23:13:01

这个我也想知道,帮顶一下.

happytc 发表于 2011-8-18 08:41:36

如何才能直接通过$HBITMAP这个图像句柄,直接得到和$str相同的数据?
gto250 发表于 2011-8-15 20:59 http://www.autoitx.com/images/common/back.gif


#Include <WinAPI.au3>
#Include <ScreenCapture.au3>

$hBITMAP = _ScreenCapture_Capture()
$Re = hBITMAP2Binary($hBITMAP)
MsgBox(0,0,$Re)

Func hBITMAP2Binary($hBITMAP)
        Local $DLL, $sBITMAP, $MemSize, $MemPtr, $bByte, $sBit, $bBit
       
        $DLL = DllOpen("gdi32.dll")
        $sBITMAP = DllStructCreate("long Type;long Width;long Height;long WidthBytes;ushort Plane;ushort BitsPixel;ptr Bits")
        $MemSize = DllStructGetSize($sBITMAP)
        $MemPtr = DllStructGetPtr($sBITMAP)
        _WinAPI_GetObject($hBITMAP, $MemSize, $MemPtr)
        $bByte = DllStructGetData($sBITMAP, "Width") * DllStructGetData($sBITMAP, "Height") * DllStructGetData($sBITMAP, "BitsPixel") / 8
        $sBit = DllStructCreate("byte[" & $bByte & "]")
        DllCall($DLL, "dword", "GetBitmapBits", "ptr", $hBITMAP, "dword", DllStructGetSize($sBit), "ptr", DllStructGetPtr($sBit))
        _WinAPI_DeleteObject($hBITMAP)
        DllClose($DLL)
        $bBit = DllStructGetData($sBit, 1)
        Return StringTrimLeft($bBit, 2)
EndFunc


也可以用GDI+来搞,就是先创建Stream,然后通过Stream的指针访问内存块来得到

gto250 发表于 2011-8-18 20:07:50

回复 3# happytc

兄弟确定得到的数据$Re和我保存$hBITMAP为图片后再以16进制打开FileRead出来的$str数据相同??

我试了,得到的数据是不一样的!用GetBitmapBits得到的是颜色的数据

happytc 发表于 2011-8-19 23:26:39

回复 4# gto250


当然不一样了,因为你保存时得有图片格式,于是进行转换压缩了,那要是一样了,才是怪事

happytc 发表于 2011-8-20 00:27:10

你要这样来验証呀,看来用GDI+更明显点


#include <ButtonConstants.au3>
#include <Memory.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>


Main()

Func Main()
        Local $HBITMAP, $HBITMAPbak, $bImage, $hGUI, $iButton, $hButton, $iPic, $hHBITMAP, $msg, $JPEG_Quality = 100
       
        _GDIPlus_Startup()
        $HBITMAP = _ScreenCapture_Capture("", 0, 0, 100, 100)
        $HBITMAPbak = $HBITMAP
        $HBITMAP = _GDIPlus_BitmapCreateFromHBITMAP($HBITMAP)
        $bImage = HBitmap2Binary($HBITMAP, $JPEG_Quality)
        _ScreenCapture_SetJPGQuality($JPEG_Quality)
        _ScreenCapture_SaveImage("f:\a.jpg", $HBITMAPbak)
        $hGUI = GUICreate("Test", 300, 300)
        $iButton = GUICtrlCreateButton("", 0, 0, 100, 100, $BS_BITMAP)
        $iPic = GUICtrlCreatePic("f:\a.jpg", 110, 0, 100, 100)
        $hButton = GUICtrlGetHandle($iButton)
        $hHBITMAP = Load_BMP_From_Mem($bImage, True)
        _SendMessage($hButton, $BM_SETIMAGE, 0, $hHBITMAP)
        _GDIPlus_Shutdown()
       
        GUISetState(@SW_SHOW, $hGUI)

        While True
                $msg = GUIGetMsg()
                Switch $msg
                        Case -3, $iButton
                                ExitLoop
                EndSwitch
        WEnd
        _WinAPI_DeleteObject($hHBITMAP)
        GUIDelete($hGUI)
EndFunc

Func Load_BMP_From_Mem($mem_image, $hHBITMAP = False)
    If Not IsBinary($mem_image) Then Return SetError(1, 0, 0)
    Local $declared = True
    If Not $ghGDIPDll Then
      _GDIPlus_Startup()
      $declared = False
    EndIf
    Local Const $memBitmap = Binary($mem_image)
    Local Const $len = BinaryLen($memBitmap)
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE)
    Local Const $pData = _MemGlobalLock($hData)
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData)
    DllStructSetData($tMem, 1, $memBitmap)
    _MemGlobalUnlock($hData)
    Local $hStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0)
    $hStream = $hStream
    Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0)
    $hBitmap = $hBitmap
    Local Const $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
                                           "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    $tMem = 0
    If $hHBITMAP Then
      Local Const $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
      _GDIPlus_BitmapDispose($hBitmap)
      If Not $declared Then _GDIPlus_Shutdown()
      Return $hHBmp
    EndIf
    If Not $declared Then _GDIPlus_Shutdown()
    Return $hBitmap
EndFunc


Func HBitmap2Binary($hBitmap, $JPEG_Quality = 100)
        Local $aStream, $Stream, $JpgGUID, $tagGUID, $Ptr, $tParams, $pParams, $tData, $pData, $aMemory, $Memory, $MemSize, $MemPtr, $dStruct, $bString, $tStruct, $aCall
        Local $declared = True
    If Not $ghGDIPDll Then
      _GDIPlus_Startup()
      $declared = False
    EndIf

    $aStream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", 1, "ptr*", 0)
    $Stream = $aStream
    $JpgGUID = _GDIPlus_EncodersGetCLSID("JPG")
    $tagGUID = _WinAPI_GUIDFromString($JpgGUID)
    $Ptr = DllStructGetPtr($tagGUID)
    $tParams = _GDIPlus_ParamInit(1)
    $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", $JPEG_Quality)
    $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    $pParams = DllStructGetPtr($tParams)
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $Stream, "ptr", $Ptr, "ptr", $pParams)
    $tData = 0
    $tParams = 0
    $aMemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $Stream, "ptr*", 0)
    $Memory = $aMemory
    $MemSize = _MemGlobalSize($Memory)
    $MemPtr = _MemGlobalLock($Memory)
    $dStruct = DllStructCreate("byte[" & $MemSize & "]", $MemPtr)
    $bString = DllStructGetData($dStruct, 1)
    $tStruct = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $Stream, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tStruct))
    _MemGlobalFree($Memory)
    If Not $declared Then _GDIPlus_Shutdown()
    Return $bString
EndFunc

happytc 发表于 2011-8-20 09:36:44

你太热情了,居然还给:金钱 + 15 块 贡献 + 15 分

gto250 发表于 2011-8-20 19:32:33

因为这个对我有帮助!!!

楼上风云 发表于 2011-8-22 11:55:08

3楼是高手,膜拜

风尘子 发表于 2011-12-5 22:08:53

留个脚印等下看{:face (355):}

hsyl4125 发表于 2015-5-20 14:50:28

学习学习学习

yinui 发表于 2017-3-3 13:48:37

强大,谢谢共享
页: [1]
查看完整版本: 如何通过图片文件的句柄获得图片的二进制数据【已解决】