Andreik

GdipSaveImageToStream and Win 8.1

4 posts in this topic

Can someone try to call this function from gdiplus.dll on a Windows 8.1 machine and confirm that is working or not? I am pretty sure it worked well on other versions but now I still get this error:

 

+>16:15:55 Starting AutoIt3Wrapper v.14.801.2025.0 SciTE v.3.4.4.0   Keyboard:00000809  OS:WIN_81/  CPU:X64 OS:X64    Environment(Language:0809)

!>16:09:50 AutoIt3.exe ended.rc:-1073741819

 

A simple code for test can be this one:

#AutoIt3Wrapper_UseX64=n
#include <ScreenCapture.au3>
#include <Memory.au3>


_GDIPlus_Startup()

Local $hBitmap = _ScreenCapture_Capture('',0,0,-1,-1,False)
_GDIPlus_SaveImageToStream($hBitmap)
_GDIPlus_Shutdown()

Func _GDIPlus_SaveImageToStream($hBitmap, $iQuality = 50, $Encoder = "jpg") ;coded by Andreik, modified by UEZ, FS
    Local $tParams
    Local $tData
    Local $pData
    Local $pParams

    Local $sImgCLSID = _GDIPlus_EncodersGetCLSID($Encoder)
    Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
    Local $pEncoder = DllStructGetPtr($tGUID)

    If $Encoder == "jpg" Or $Encoder == "jpeg" Then
        $tParams = _GDIPlus_ParamInit(1)
        $tData = DllStructCreate("int Quality")
        DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
        $pData = DllStructGetPtr($tData)
        _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
        $pParams = DllStructGetPtr($tParams)
    Else
        $pParams = 0
    EndIf

    Local $hStream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", True, "ptr*", 0)
    If @error Then Return SetError(1, 0, 0)
    $hStream = $hStream[3]
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $hStream, "ptr", $pEncoder, "ptr", $pParams)
    _GDIPlus_BitmapDispose($hBitmap)
    Local $hMemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $hStream, "ptr*", 0)
    If @error Then Return SetError(2, 0, 0)

    $hMemory = $hMemory[2]
    Local $iMemSize = _MemGlobalSize($hMemory)
    Local $pMem = _MemGlobalLock($hMemory)

    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    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, "ptr", DllStructGetPtr($tVARIANT)) ;<a href='http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85' class='bbc_url' title='External link' rel='nofollow external'>http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85</a>).aspx
    _MemGlobalFree($hMemory)

    Return $bData
EndFunc   ;==>_GDIPlus_SaveImageToStream

When the words fail... music speaks

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

The crash occurs because you provide a GDI bitmap handle to the functions not a GDI+ bitmap handle.

Try this:

 

Local $hHBitmap = _ScreenCapture_Capture('',0,0,-1,-1,False)
Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
_GDIPlus_SaveImageToStream($hBitmap)
_WinAPI_DeleteObject($hHBitmap)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()

I create this version some time ago which is based on your version:

Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = @ScriptDir & "\Converted.jpg") ;coded by UEZ 2013 build 2014-01-25; based on the code by Andreik
    Local $sImgCLSID, $tGUID, $tParams, $tData
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            $tData = DllStructCreate("int Quality")
            DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
            Local $pData = DllStructGetPtr($tData)
            $tParams = _GDIPlus_ParamInit(1)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
        Case "PNG", "BMP", "GIF", "TIF"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch
    Local $hStream = _WinAPI_CreateStreamOnHGlobal() ;http://msdn.microsoft.com/en-us/library/ms864401.aspx
    If @error Then Return SetError(2, 0, 0)
    _GDIPlus_ImageSaveToStream($hBitmap, $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams))
    If @error Then Return SetError(3, 0, 0)

    Local $hMemory = _WinAPI_GetHGlobalFromStream($hStream) ;http://msdn.microsoft.com/en-us/library/aa911736.aspx
    If @error Then Return SetError(4, 0, 0)
    Local $iMemSize = _MemGlobalSize($hMemory)
    If Not $iMemSize Then Return SetError(5, 0, 0)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    _WinAPI_ReleaseStream($hStream) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85).aspx
    _MemGlobalFree($hMemory)
    If $bSave Then
        Local $hFile = FileOpen($sFilename, 18)
        If @error Then Return SetError(6, 0, $bData)
        FileWrite($hFile, $bData)
        FileClose($hFile)
    EndIf
    Return $bData
EndFunc   ;==>_GDIPlus_StreamImage2BinaryString

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

I tried in window 7 x86 and it does not.

Saludos

Share this post


Link to post
Share on other sites

^^ Yup, I was blind and didn't see that _ScreenCapture_Capture() returns HBITMAP. Thank you!


When the words fail... music speaks

Share this post


Link to post
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

  • Similar Content

    • cyanidemonkey
      By cyanidemonkey
      Hi guys,
      I am writing an automated website test script and have a page with some download links to test.
      The site is in ASP.NET MVC, the download link is like this: https://websiteurl.com/services/download?linkAddress=download%2Finteractive-sdk.zip
      I can click the link via the DOM and IE11 brings up the download message at the botton of the window.
      When I used Au3Info.exe and mouse over the download dialog I see:
      >>>> Control <<<< Class: DirectUIHWND Instance: 1 ClassnameNN: DirectUIHWND1 Name: Advanced (Class): [CLASS:DirectUIHWND; INSTANCE:1] ID: Text: etc... I tried using:
      WinGetClassList()
      But it showed the class name "DirectUIHWND1" before and after download dialog appeared in browser.
      so I thought maybe it was just hidden, so I tried:
      ControlCommand( "[CLASS:DirectUIHWND; INSTANCE:1]", "", "", "IsVisible", "") but is returned 0 both before and after download dialog appeared in browser.
       
      So I guess I am going about it the wrong way. Does anyone have an idea, or exampe of checking for the IE11 download dialog or perhaps another method of verifying the file is availble for download?