Mbee Posted June 7, 2016 Share Posted June 7, 2016 (edited) You can readily create a bitmap from the binary data that's read in from a file (via a simple binary FileRead) using _GDIPlus_BitmapCreateFromMemory(). But how do you do the reverse? That is, to generate/copy the binary data back from the bitmap so that it's the same as if you performed a binary FileRead()? After reading all kinds of things on this issue, both here in the AutoIt fora and non-AutoIt sources elsewhere, I still haven't been able to find the answer. At first it seemed like _GDIPlus_BitmapLockBits() might be part of the solution, but I'm still a GDIPlus newbie and I can't understand if that's the right approach (and if so, how to actually code it all), or if there's an easier solution. Any guidance, please? Thanks! Edited June 7, 2016 by Mbee Link to comment Share on other sites More sharing options...
Mbee Posted June 7, 2016 Author Share Posted June 7, 2016 (edited) Well, since no general assistance was provided for my OP, I've tried to figure it out on my own, with partial success. Unfortunately, there's some kind of bug in the code I've tried to put together (I've borrowed heavily from Andreik's code seen here - thanks Andreik!). Look for the comment reading "THIS IS WHERE I ALWAYS GET AN ERROR!". (Variables not defined in this function are global or otherwise supplied outside the func) expandcollapse popupFunc _MyBytesFromBitmap( ByRef $arg_Mem_Size, $arg_BitmapHdl, $arg_Tag_Encoder_Ptr ) ; ; NOTE: _GDIPlus_Startup() MUST have already been called ; Local $Lf_BitmapObjHdl = _GDIPlus_BitmapCreateFromHBITMAP($arg_BitmapHdl) If $Lf_BitmapObjHdl = 0 Then ; Error in call $L_error = @error $L_extended = @extended SetError ( $L_error, $L_extended, "" ) Return "" EndIf ; Local $Lf_Stream = DllCall($hGIFDLL__OLE32,"uint","CreateStreamOnHGlobal","ptr",0,"bool",1,"ptr*",0) If @error <> 0 Then $L_error = @error $L_extended = @extended SetError ( $L_error, $L_extended, "" ) Return "" EndIf ; DllCall($G_GDIPlusSDllHdl,"uint","GdipSaveImageToStream","ptr",$Lf_BitmapObjHdl,"ptr",$Lf_Stream[3],"ptr",$arg_Tag_Encoder_Ptr,"ptr",0) If @error <> 0 Then $L_error = @error $L_extended = @extended SetError ( $L_error, $L_extended, "" ) Return "" EndIf ; _GDIPlus_BitmapDispose($Lf_BitmapObjHdl) ; Local $Lf_Memory = DllCall("ole32.dll","uint","GetHGlobalFromStream","ptr",$Lf_Stream[3],"ptr*",0) If @error <> 0 Then ;-----> THIS IS WHERE I ALWAYS GET AN ERROR! $L_error = @error $L_extended = @extended SetError ( $L_error, $L_extended, "" ) Return "" EndIf ; $arg_Mem_Size = _MemGlobalSize($Lf_Memory[2]) Local $Lf_MemPtr = _MemGlobalLock($Lf_Memory[2]) Local $Lf_MemStruct = DllStructCreate("byte[" & $arg_Mem_Size & "]", $Lf_MemPtr) Local $Lf_Data = DllStructGetData($Lf_MemStruct,1) _MemGlobalFree($Lf_Memory[2]) ; SetError ( $L_error, $L_extended, $Lf_Data ) Return $Lf_Data EndFunc What am I doing wrong there? Thanks! Edited June 7, 2016 by Mbee Link to comment Share on other sites More sharing options...
UEZ Posted June 7, 2016 Share Posted June 7, 2016 Try this: expandcollapse popup;Coded by UEZ 2013 -> This program requires AutoIt version 3.3.9.21 or higher! #include <GDIPlus.au3> #include <Memory.au3> _GDIPlus_Startup() Global $sFile = StringReplace(@AutoItExe, "autoit3.exe", "Examples\GUI\msoobe.jpg") Global $hImage = _GDIPlus_ImageLoadFromFile($sFile) Global $hBitmap = _GDIPlus_ImageResize($hImage, 10, 7) Global $bImage = _GDIPlus_StreamImage2BinaryString($hBitmap) ConsoleWrite("Error: " & @error & @LF) ConsoleWrite(BinaryLen($bImage) & @CRLF) MsgBox(0, "Binary", $bImage) _GDIPlus_ImageDispose($hImage) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() 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 It will return a binary string which can be saved. DinFuv, guiltyking and BigDaddyO 2 1 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Mbee Posted June 8, 2016 Author Share Posted June 8, 2016 That works! Hey, thanks a great deal, UEZ! A key part of my problem was that I was calling trancexx's _GIF_ResizeBitmap() instead of _GDIPlus_ImageResize(). I made a few minor changes to adapt your code to my naming standards and to adapt it to the fact that some external values were already known prior to the call. Here's the result... expandcollapse popup; ; Coded by UEZ 2013 -> This program requires AutoIt version 3.3.9.21 or higher! ; Func _UEZ_BinaryStringFromBitmapHdl($hBitmap, $sFormat, $iQuality = 100) ;coded by UEZ 2013 build 2014-01-25 ; (based on the code by Andreik) ; Local $Lf_EncoderCLSIDStr = _GDIPlus_EncodersGetCLSID( $sFormat ) ; Get info for encoder of this pic type Local $Lf_EncoderGUIDTagStruct = _WinAPI_GUIDFromString($Lf_EncoderCLSIDStr) Local $Lf_EncoderGUIDTagStructPtr = DllStructGetPtr( $Lf_EncoderGUIDTagStruct ) ; Local $tGUID, $tParams = 0, $tData $tGUID = $Lf_EncoderGUIDTagStruct If $sFormat = "JPG" Then $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) EndIf Local $hStream = _WinAPI_CreateStreamOnHGlobal() ;http://msdn.microsoft.com/en-us/library/ms864401.aspx If @error Then Return SetError(2, 0, 0) If $tParams <> 0 Then _GDIPlus_ImageSaveToStream($hBitmap, $hStream, $Lf_EncoderGUIDTagStructPtr, DllStructGetPtr($tParams)) Else _GDIPlus_ImageSaveToStream($hBitmap, $hStream, $Lf_EncoderGUIDTagStructPtr) EndIf 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) Return $bData EndFunc ;==>_UEZ_BinaryStringFromBitmap I am very grateful for your kind assistance! 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