找回密码
 加入
搜索
查看: 12394|回复: 11

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

 火.. [复制链接]
发表于 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相同的数据?
发表于 2011-8-15 23:13:01 | 显示全部楼层
这个我也想知道,帮顶一下.
发表于 2011-8-18 08:41:36 | 显示全部楼层
如何才能直接通过$HBITMAP这个图像句柄,直接得到和$str相同的数据?
gto250 发表于 2011-8-15 20:59



#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的指针访问内存块来得到
 楼主| 发表于 2011-8-18 20:07:50 | 显示全部楼层
回复 3# happytc

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

我试了,得到的数据是不一样的!用GetBitmapBits得到的是颜色的数据
发表于 2011-8-19 23:26:39 | 显示全部楼层
回复 4# gto250


  当然不一样了,因为你保存时得有图片格式,于是进行转换压缩了,那要是一样了,才是怪事
发表于 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[3]
    Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0)
    $hBitmap = $hBitmap[2]
    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[3]
    $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[2]
    $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

评分

参与人数 1金钱 +15 贡献 +15 收起 理由
gto250 + 15 + 15 非常感谢!!

查看全部评分

发表于 2011-8-20 09:36:44 | 显示全部楼层
你太热情了,居然还给:金钱 + 15 块 贡献 + 15 分
 楼主| 发表于 2011-8-20 19:32:33 | 显示全部楼层
因为这个对我有帮助!!!
发表于 2011-8-22 11:55:08 | 显示全部楼层
3楼是高手,膜拜
发表于 2011-12-5 22:08:53 | 显示全部楼层
留个脚印等下看
发表于 2015-5-20 14:50:28 | 显示全部楼层
学习学习学习
发表于 2017-3-3 13:48:37 | 显示全部楼层
强大,谢谢共享
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-26 13:29 , Processed in 0.073200 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表