zagibu Posted May 11, 2008 Share Posted May 11, 2008 I'm trying to write an ImageSearch routine similar to the one in AutoHotkey, and I'm stuck with a (probably) very amateuri-ish problem. _ScreenCapture_Capture("") is returning a HBITMAP handle. What do I do with that? I just want the raw bitmap data (the same I would get by using a binary FileOpen/FileRead on a bitmap file). I don't want to let ScreenCapture create the file, then read it from there, because that would lead to a lot of disk access. Thanks in advance. Link to comment Share on other sites More sharing options...
ProgAndy Posted May 11, 2008 Share Posted May 11, 2008 What do you want to do with it?Set to Image Control? Look at _SetBitmapToCtrl from resources.au3Or use other functions from GDIPlus *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
zagibu Posted May 11, 2008 Author Share Posted May 11, 2008 I just need the raw byte data...I need it to do comparisons byte-wise. Link to comment Share on other sites More sharing options...
zagibu Posted May 11, 2008 Author Share Posted May 11, 2008 There is a Function called _GDIPlus_BitmapCreateFromHBITMAP, which is supposed to take a HBITMAP and return a "bitmap object". But I don't see anything that can be used to access the bitmap data. It's probably so obvious that noone can be bothered to post it... Link to comment Share on other sites More sharing options...
Siao Posted May 11, 2008 Share Posted May 11, 2008 Even though MS defines GetBitmapBits/SetBitmapBits to be obsolete, you can still use them: #include <WinAPI.au3> #Include <ScreenCapture.au3> $hBmp = _ScreenCapture_Capture("", 0, 0, 16, 16) $aSize = DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBmp, 'int', 0, 'ptr', 0) If $aSize[0] Then $tBits = DllStructCreate('byte[' & $aSize[0] & ']') DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBmp, 'int', $aSize[0], 'ptr', DllStructGetPtr($tBits)) $sHex = Hex(DllStructGetData($tBits, 1)) MsgBox(0, '', $sHex) EndIf _WinAPI_DeleteObject($hBmp) Exit "be smart, drink your wine" Link to comment Share on other sites More sharing options...
zagibu Posted May 11, 2008 Author Share Posted May 11, 2008 Cool, thanks a lot. Just on a side note: what would be a non-obsolete way of doing it? Link to comment Share on other sites More sharing options...
Siao Posted May 11, 2008 Share Posted May 11, 2008 That would be GetDIBits, but for that you also need the handle to DC in which the bitmap is selected, so you'd have to do what _ScreenCapture_Capture() does and call GetDIBits after BitBlt. "be smart, drink your wine" Link to comment Share on other sites More sharing options...
zagibu Posted May 12, 2008 Author Share Posted May 12, 2008 Hmmm, what about this: $hbmp = _ScreenCapture_Capture("") $himg = _GDIPlus_BitmapCreateFromHBITMAP($hbmp) $gfx = _GDIPlus_ImageGetGraphicsContext($himg) $dc = _GDIPlus_GraphicsGetDC($gfx) And then use GetDIBits? Link to comment Share on other sites More sharing options...
zagibu Posted May 12, 2008 Author Share Posted May 12, 2008 (edited) Your solution works fine, BTW, thanks a lot, Siao. A problem is, that I get a 32bit BMP, though, no matter what I set with _ScreenCapture_SetBMPFormat(). Anyone see a quick operation to dump the additional byte? Or a way to get a 24bit BMP that needs no post-processing? Edited May 12, 2008 by zagibu Link to comment Share on other sites More sharing options...
Siao Posted May 12, 2008 Share Posted May 12, 2008 #include <WinAPI.au3> Const $DIB_RGB_COLORS = 0 $iWidth = 16;@DesktopWidth $iHeight = 16;@DesktopHeight $iBitCount = 24 $tBMI = DllStructCreate($tagBITMAPINFO) DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4) DllStructSetData($tBMI, "Width", $iWidth) DllStructSetData($tBMI, "Height", -$iHeight) DllStructSetData($tBMI, "Planes", 1) DllStructSetData($tBMI, "BitCount", $iBitCount) $hDC = _WinAPI_GetDC(0) $hCDC = _WinAPI_CreateCompatibleDC($hDC) $aDIB = DllCall('gdi32.dll','ptr','CreateDIBSection', 'ptr',0, 'ptr',DllStructGetPtr($tBMI), 'uint',$DIB_RGB_COLORS, 'ptr*',0, 'ptr',0, 'uint',0) _WinAPI_DeleteObject(_WinAPI_SelectObject($hCDC, $aDIB[0])) _WinAPI_BitBlt($hCDC, 0, 0, $iWidth, $iHeight, $hDC, 0, 0, $SRCCOPY) $tBits = DllStructCreate('byte[' & $iWidth*$iHeight*$iBitCount/8 & ']', $aDIB[4]) $sHex = Hex(DllStructGetData($tBits, 1)) MsgBox(0, '', $sHex) _WinAPI_DeleteObject($aDIB[0]) _WinAPI_DeleteDC($hCDC) _WinAPI_ReleaseDC(0, $hDC) "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Malkey Posted May 13, 2008 Share Posted May 13, 2008 $aDIB = DllCall('gdi32.dll','ptr','CreateDIBSection', 'ptr',0, 'ptr',DllStructGetPtr($tBMI), 'uint',$DIB_RGB_COLORS, 'ptr*',0, 'ptr',0, 'uint',0)I had been trying to use GetDIBits, without success. Thank-you very much, Siao. This entire script is very helpful. Link to comment Share on other sites More sharing options...
Insomniax Posted June 26, 2008 Share Posted June 26, 2008 I had been trying to use GetDIBits, without success.Thank-you very much, Siao. This entire script is very helpful.what if i want to read a .bmp file with the same format? this seems to read a region in a desktop so i want to compare the 2.Thanks. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now