Jump to content

CreateStreamOnHGlobal issue


Go to solution Solved by Yashied,

Recommended Posts

Hi,

I made an example named "IP Camera", basically you need to know that it converts binary data to bitmap using the recent _GDIPlus_BitmapCreateFromMemory function.

The script works fine for almost two hours. Then the _GDIPlus_BitmapCreateFromMemory is not able to convert the binary data (which is valid I checked it) to a bitmap and returns the error 2 which corresponds to the _WinAPI_CreateStreamOnHGlobal function.

I first tried to shutdown and restart the GDIPlus library because I didn't know the issue was from a WinAPI function (so it didn't work).

I'm wondering if it's possible that the function stops working after a huge number of calls? (does not make sense but I don't see what's wrong here).

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

@FireFox

You should release each stream object by using _WinAPI_ReleaseStream() function, otherwise you get a memory leak. Please carefully read the documentation.

P.S.

$hStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $hData, "int", True, "ptr*", 0)

Edited by Yashied
Link to comment
Share on other sites

It is.

Here is the function:

;==================================================================================================================================
; Author ........: UEZ
; Modified.......: progandy
;===================================================================================================================================
Func _GDIPlus_BitmapCreateFromMemory($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image saved in variable (memory) and convert it to binary
    Local Const $iLen = BinaryLen($memBitmap) ;get binary length of the image
    Local Const $GMEM_MOVEABLE = 0x0002
    $aResult = DllCall("kernel32.dll", "handle", "GlobalAlloc", "uint", $GMEM_MOVEABLE, "ulong_ptr", $iLen) ;allocates movable memory ($GMEM_MOVEABLE = 0x0002)
    If @error Then Return SetError(4, 0, 0)
    Local Const $hData = $aResult[0]
    $aResult = DllCall("kernel32.dll", "ptr", "GlobalLock", "handle", $hData)
    If @error Then Return SetError(5, 0, 0)
    Local Const $pData = $aResult[0] ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $iLen & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    DllCall("kernel32.dll", "bool", "GlobalUnlock", "handle", $hData) ;decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE
    If @error Then Return SetError(6, 0, 0)
    Local Const $hStream = _WinAPI_CreateStreamOnHGlobal($pData) ;creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then Return SetError(2, 0, 0)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromStream($hStream) ;creates a Bitmap object based on an IStream COM interface
    If @error Then Return SetError(3, 0, 0)
    Local $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, "struct*", $tVARIANT) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = __GDIPlus_BitmapCreateDIBFromBitmap($hBitmap) ;supports GDI transparent color format
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateFromMemory

 

And if you need the interesting part of the script:

$hBMP = _GDIPlus_BitmapCreateFromMemory($bStream)
 
;~ $hBMP = _GDIPlus_ScaleImage($hBMP, $x, $y)
 
$hBITMAP2 = __GDIPlus_BitmapCreateDIBFromBitmap($hBMP)
;~ $hBITMAP2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBMP)
 
_WinAPI_DeleteObject(_SendMessage($hPicCtrl, $STM_SETIMAGE, 0, $hBITMAP2))
 
_WinAPI_DeleteObject($hBITMAP2)
 
_GDIPlus_ImageDispose($hBMP)

Br, FireFox.

Link to comment
Share on other sites

  • Solution
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...