jwilliam Posted November 20, 2012 Posted November 20, 2012 I'm trying to use a function from the leptonica dll. It seems like it should be straightforward, but I'm having no luck with it. From the documentation: typedef unsigned char l_uint8 PIX* pixReadMemBmp(const l_uint8 *cdata, size_t size) Then, in AutoIT, I have: $leptonicaHandle = DllOpen("path\to\liblept168.dll"); $image = _ScreenCapture_Capture("", $x1, $y1, $x2, $y2); $tmp = _GDIPlus_BitmapCreateFromHBITMAP($image); $width = _GDIPlus_ImageGetWidth($tmp); $height = _GDIPlus_ImageGetHeight($tmp); $pix = DllCall($leptonicaHandle, "ptr:cdecl", "pixReadMemBmp", "str", $image, "ULONG_PTR", (($width * $height * 24) + 54)); ; @error == 0 ; $pix[0] == 0x000000 There are no errors when this executes. The call to pixReadMemBmp just returns a bad memory address every time. I read that HBITMAP can be type-cast into uchar * without issue, but I think this may be where my code is off. I have "str" above, but I've tried "str*", "ptr" and "handle" as well. Also, the last parameter to DllCall is supposed to be the size of the bitmap in bytes (width * height * 24bits/pixel) + 54bytesforheader. I'm not 100% sure this is correct, but I couldn't find any AutoIT functions to get image size from an HBITMAP. I'd appreciate any thoughts on this. Thanks...
BrewManNH Posted November 20, 2012 Posted November 20, 2012 Actually the documentation says this also. Read/write to memory [only on linux] PIX *pixReadMemBmp() l_int32 pixWriteMemBmp() If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator
jwilliam Posted November 20, 2012 Author Posted November 20, 2012 Thanks a lot, BrewMan. I completely missed that. Back to the drawing board...
WarMan Posted January 20 Posted January 20 In case someone found this topic on the search engines, here is how to create a pix object from a bitmap object expandcollapse popup#include <WinAPIGdi.au3> #include <WinAPIGdiDC.au3> #include <WinAPIHObj.au3> #include <Memory.au3> #include <ScreenCapture.au3> Local $hLeptonicaDll = DllOpen(@ScriptDir & "\liblept168.dll") If $hLeptonicaDll = -1 Then Exit Local $hBitmap = _ScreenCapture_Capture() Local $pPix = _CreatePixFromHBITMAP($hBitmap) ConsoleWrite("Pix object: " & $pPix & @CR) _WinAPI_DeleteObject($hBitmap) DllCall($hLeptonicaDll, "none:cdecl", "pixDestroy", "ptr*", $pPix) DllClose($hLeptonicaDll) Func _CreatePixFromHBITMAP($hHBITMAP) ; Get bitmap information Local $tBITMAP = DllStructCreate($tagBITMAP) _WinAPI_GetObject($hHBITMAP, DllStructGetSize($tBITMAP), DllStructGetPtr($tBITMAP)) If @error Then Return SetError(1, 0, 0) Local $iWidth = DllStructGetData($tBITMAP, "bmWidth") Local $iHeight = Abs(DllStructGetData($tBITMAP, "bmHeight")) ; Get a device context Local $hDC = _WinAPI_GetDC(0) If $hDC = 0 Then Return SetError(2, 0, 0) ; Get pix object Local $pPix = DllCall($hLeptonicaDll, "ptr:cdecl", "pixCreate", "int", $iWidth, "int", $iHeight, "int", 32) If @error Or $pPix[0] = 0 Then _WinAPI_ReleaseDC(0, $hDC) Return SetError(3, 0, 0) EndIf $pPix = $pPix[0] ; Get the pointer to Leptonica's allocated memory Local $pPixData = DllCall($hLeptonicaDll, "ptr:cdecl", "pixGetData", "ptr", $pPix) If @error Or $pPixData[0] = 0 Then _WinAPI_ReleaseDC(0, $hDC) DllCall($hLeptonicaDll, "none:cdecl", "pixDestroy", "ptr*", $pPix) Return SetError(4, 0, 0) EndIf $pPixData = $pPixData[0] ; Create a 32 bit HBITMAP copy if needed Local $bDeleteHBITMAP = False If DllStructGetData($tBITMAP, "bmBitsPixel") <> 32 Then $hHBITMAP = _Create32HBITMAP($hHBITMAP, $iWidth, $iHeight) If @error Then _WinAPI_ReleaseDC(0, $hDC) DllCall($hLeptonicaDll, "none:cdecl", "pixDestroy", "ptr*", $pPix) Return SetError(5, 0, 0) EndIf $bDeleteHBITMAP = True EndIf ; Create BITMAPINFOHEADER Local $tBIHDR = DllStructCreate("dword biSize;long biWidth;long biHeight;WORD biPlanes;WORD biBitCount;dword biCompression;dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant;") DllStructSetData($tBIHDR, "biSize", DllStructGetSize($tBIHDR)) DllStructSetData($tBIHDR, "biWidth", $iWidth) DllStructSetData($tBIHDR, "biHeight", -$iHeight) ; Negative for top-down DIB DllStructSetData($tBIHDR, "biPlanes", 1) DllStructSetData($tBIHDR, "biBitCount", 32) DllStructSetData($tBIHDR, "biCompression", 0) ; BI_RGB ; Calculate buffer size Local $iRowSize = Int(($iWidth * 32 + 31) / 32) * 4 Local $iImageSize = $iRowSize * $iHeight ; Allocate temporary buffer for GetDIBits Local $pTempBuffer = _MemVirtualAlloc(0, $iImageSize, 0x1000, 0x04) If $pTempBuffer = 0 Then _WinAPI_ReleaseDC(0, $hDC) DllCall($hLeptonicaDll, "none:cdecl", "pixDestroy", "ptr*", $pPix) If $bDeleteHBITMAP Then _WinAPI_DeleteObject($hHBITMAP) Return SetError(5, 0, 0) EndIf ; Get the pixel data _WinAPI_GetDIBits($hDC, $hHBITMAP, 0, $iHeight, $pTempBuffer, DllStructGetPtr($tBIHDR), $DIB_RGB_COLORS) ; Copy data into Leptonica's buffer DllCall("kernel32.dll", "none", "RtlMoveMemory", "ptr", $pPixData, "ptr", $pTempBuffer, "ulong_ptr", $iImageSize) _WinAPI_ReleaseDC(0, $hDC) _MemVirtualFree($pTempBuffer, 0, 0x8000) ; Free our temporary buffer If $bDeleteHBITMAP Then _WinAPI_DeleteObject($hHBITMAP) Return $pPix EndFunc ;==>_CreatePixFromHBITMAP Func _Create32HBITMAP($hBitmap, $iWidth, $iHeight) ; Create 32-bit bitmap Local $hDC = _WinAPI_GetDC(0) Local $hBitmap32 = _WinAPI_CreateCompatibleBitmapEx($hDC, $iWidth, $iHeight, 0xFF000000) ; Black with alpha=255 _WinAPI_ReleaseDC(0, $hDC) If $hBitmap32 = 0 Then Return SetError(1, 0, 0) ; Use AlphaBlend for format conversion Local $hDC1 = _WinAPI_CreateCompatibleDC(0) Local $hDC2 = _WinAPI_CreateCompatibleDC(0) Local $hOld1 = _WinAPI_SelectObject($hDC1, $hBitmap) Local $hOld2 = _WinAPI_SelectObject($hDC2, $hBitmap32) ; AlphaBlend automatically handles format conversion and sets alpha _WinAPI_AlphaBlend($hDC2, 0, 0, $iWidth, $iHeight, $hDC1, 0, 0, $iWidth, $iHeight, 255) _WinAPI_SelectObject($hDC1, $hOld1) _WinAPI_SelectObject($hDC2, $hOld2) ; Clean up _WinAPI_DeleteDC($hDC1) _WinAPI_DeleteDC($hDC2) Return $hBitmap32 EndFunc ;==>_Create32HBITMAP KaFu 1
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