Jump to content

PNG with Alpha channel Base64 string > Alpha channel is Black


Go to solution Solved by UEZ,

Recommended Posts

Hello Forum,

I have a PNG with Alpha channel and i converted it into an Base64 string.
Goal is to have a Logo for a Word document but not a File.png on HDD.
When i paste the image from the clipboard (manually for now) then the Alpha channel is black and not transparent.
How can i achieve a transparent background?
I tested in MS Paint, Krita and Word. All black background.

Thanks!
 

The code:

#include <Word.au3>
#include "WordConstants.au3"
#include <GDIPlus.au3>
#include <Clipboard.au3>

_GDIPlus_Startup()
Global $hBitmapGDI = _GDIPlus_BitmapCreateFromMemory(_Base64String(), True) ;       False = bitmap(GDI+), True = hbitmap(GDI) will be created
;Global $hBitmapInfo = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmapGDI)
Global $hClipboard_Bitmap = _WinAPI_CopyImage($hBitmapGDI, 0, 0, 0, $LR_DEFAULTCOLOR)
_ClipBoard_Open(0)
_ClipBoard_Empty() ; Must empty or previous image stays
_ClipBoard_SetDataEx($hClipboard_Bitmap, $CF_BITMAP)
_ClipBoard_Close()
_WinAPI_DeleteObject($hBitmapGDI)
_WinAPI_DeleteObject($hClipboard_Bitmap)
_GDIPlus_Shutdown()
Exit

The image:

Func _Base64String($bSaveBinary = False, $sSavePath = @ScriptDir)
    Local $Base64String
    $Base64String &= 'm7MAiVBORw0KGgoAAAAADUlIRFIlAHBkARgIBgAocOIElVQAGAlwSFlzEAAACxIBDAHS3QB+/AAAA3RJRABBVHgB7ZsxbwDTUBSFDWKq1ACVSmwMwNof0ACNhQXGDsxIlQC6UcHGPwC1WwAlpM79AbCwsADxA7oCAxsSWQCROnM+iFOSWgCJRJN3bsq50gBVHDt59/g79gDzs/PSdYkQCAKBQgJ1JnCjvPgAvcMhidta+UAAeUe5Of7AT70Afld+Vp6N13UA3duDyeI6LKwAiyEbgvlU+UQA+VDJ+3lxro0AH5XvlKdK3g8ARzHD/IYMnwEAPbzbWnip3FcALjKh/87sK2YAHCtfK0ezG6sAnUE3Lwmss+IAuaR8U75Q/qsAGewN36UN2qIAzdJR0RDOCroAGi4eVzFiFjwAbdEmbVOjZFQAM4SL9Sfl4xUA0qJtalCrXFQAMgRAH5T3GlAAoga1yplS5aIAThfCUdvCDJUAmcRXLe0oR5MANf2CafRV5QwAORGH1maAnpoA1C4TFQxh5LMAymvGItjULjMA+mrfZU3fd9AAVTEcXeZoapEAAUPbz7XyrvIAouv6T7ssbvoA3GZgEBrQYg8AZ5cFhH07gQsAAWhBkzWchvBAbMoO4C/6BAagALBa2DU5DeGpAG21sGtyGcIdAHKl7qo/MNBkAL17dxnCj0tVAOO+U5jLEH7pAKsaVm0uQzarCLohXQECCvvhlQDmMoQJCVXDqgDNZQizQ6qGVQCbyxCm6lSNLwBOYS5DzrTTPABhrRZoQpstXACGsMPMm6oWdgBNTkOY/VEt7ACanIbMn1HY3gAquis0WcNpCAAAjq17P10cLQBosobTEHac6QCddghjDWixxwCt5gqmf6sedQB7h6+kgRmFzgBAw8gpoK/tPgBD0HGkfN8LMgC8UhsNJaKCIQCAeKZk0lrroAAmtctE+y5reADX6S52lUzv3AAa/sjS1/5QiwC7+jtCia6q3wC7'
    $Base64String &= 'KmcIerhDfgCkbHGmUINa1gC7ctW/FJUMQQAcgHaUq7ym0AA2NcqZIU1dNQBD0EQXwuyPAwDlMofEtEWbtABdqpuSnklUNACkF8fIh+mdbwCUVzGG79IGbQCVGU1Jy2C0nwDbOyhjzso/cwCBN/QJJrFxdABf6z99VhllzQBx5PcmjvKTcQCyYlt5Lf8WzSDOJUIgBLkA/AQAfgGdGnQnr6IELMkA5QBJRU5EAK5CYII='
    $Base64String = _WinAPI_Base64Decode($Base64String)
    If @error Then Return SetError(1, 0, 0)
    Local $tSource = DllStructCreate('byte[' & BinaryLen($Base64String) & ']')
    DllStructSetData($tSource, 1, $Base64String)
    Local $tDecompress
    _WinAPI_LZNTDecompress($tSource, $tDecompress, 962)
    If @error Then Return SetError(3, 0, 0)
    $tSource = 0
    Local Const $bString = Binary(DllStructGetData($tDecompress, 1))
    If $bSaveBinary Then
        Local Const $hFile = FileOpen($sSavePath & "\Test.png", 18)
        If @error Then Return SetError(2, 0, $bString)
        FileWrite($hFile, $bString)
        FileClose($hFile)
    EndIf
    Return $bString
EndFunc   ;==>_Base64String

Func _WinAPI_Base64Decode($sB64String)
    Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "")
    Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]")
    $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($bBuffer, 1)
EndFunc   ;==>_WinAPI_Base64Decode

Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize)
    $tOutput = DllStructCreate("byte[" & $iBufferSize & "]")
    If @error Then Return SetError(1, 0, 0)
    Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", $iBufferSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0)
    If @error Then Return SetError(2, 0, 0)
    If $aRet[0] Then Return SetError(3, $aRet[0], 0)
    Return $aRet[6]
EndFunc   ;==>_WinAPI_LZNTDecompress


 

Link to comment
Share on other sites

  • Solution

Try this workaround:

#include <Word.au3>
#include "WordConstants.au3"
#include <GDIPlus.au3>
#include <Clipboard.au3>

_GDIPlus_Startup()
Global $hBitmapGDI = _GDIPlus_BitmapCreateFromMemory(_Base64String())

Global $bPNG = _GDIPlus_StreamImage2BinaryString($hBitmapGDI)

$iFormat_PNG = _ClipBoard_RegisterFormat("PNG")
_ClipBoard_Open(0)
_ClipBoard_Empty()

$iSize = BinaryLen($bPNG)
$hMemory = _MemGlobalAlloc($iSize, $GHND)
$hLock = _MemGlobalLock($hMemory)
$tData = DllStructCreate("byte png[" & $iSize & "]", $hLock)
$tData.png = Binary($bPNG)
_MemGlobalUnlock($hMemory)
MsgBox(0, "Copy Image as PNG to clipboard", _
            "Clipboard handle: " & _ClipBoard_SetDataEx($hMemory, $iFormat_PNG))
_MemGlobalFree($hMemory)

_GDIPlus_ImageDispose($hBitmapGDI)
_GDIPlus_Shutdown()
Exit

Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "PNG", $iQuality = 80, $bSave = False, $sFilename = @ScriptDir & "\Converted.jpg") ;coded by UEZ 2013 build 2014-01-25
    Local $sImgCLSID, $tGUID, $tParams
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            Local $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

Func _Base64String($bSaveBinary = False, $sSavePath = @ScriptDir)
    Local $Base64String
    $Base64String &= 'm7MAiVBORw0KGgoAAAAADUlIRFIlAHBkARgIBgAocOIElVQAGAlwSFlzEAAACxIBDAHS3QB+/AAAA3RJRABBVHgB7ZsxbwDTUBSFDWKq1ACVSmwMwNof0ACNhQXGDsxIlQC6UcHGPwC1WwAlpM79AbCwsADxA7oCAxsSWQCROnM+iFOSWgCJRJN3bsq50gBVHDt59/g79gDzs/PSdYkQCAKBQgJ1JnCjvPgAvcMhidta+UAAeUe5Of7AT70Afld+Vp6N13UA3duDyeI6LKwAiyEbgvlU+UQA+VDJ+3lxro0AH5XvlKdK3g8ARzHD/IYMnwEAPbzbWnip3FcALjKh/87sK2YAHCtfK0ezG6sAnUE3Lwmss+IAuaR8U75Q/qsAGewN36UN2qIAzdJR0RDOCroAGi4eVzFiFjwAbdEmbVOjZFQAM4SL9Sfl4xUA0qJtalCrXFQAMgRAH5T3GlAAoga1yplS5aIAThfCUdvCDJUAmcRXLe0oR5MANf2CafRV5QwAORGH1maAnpoA1C4TFQxh5LMAymvGItjULjMA+mrfZU3fd9AAVTEcXeZoapEAAUPbz7XyrvIAouv6T7ssbvoA3GZgEBrQYg8AZ5cFhH07gQsAAWhBkzWchvBAbMoO4C/6BAagALBa2DU5DeGpAG21sGtyGcIdAHKl7qo/MNBkAL17dxnCj0tVAOO+U5jLEH7pAKsaVm0uQzarCLohXQECCvvhlQDmMoQJCVXDqgDNZQizQ6qGVQCbyxCm6lSNLwBOYS5DzrTTPABhrRZoQpstXACGsMPMm6oWdgBNTkOY/VEt7ACanIbMn1HY3gAquis0WcNpCAAAjq17P10cLQBosobTEHac6QCddghjDWixxwCt5gqmf6sedQB7h6+kgRmFzgBAw8gpoK/tPgBD0HGkfN8LMgC8UhsNJaKCIQCAeKZk0lrroAAmtctE+y5reADX6S52lUzv3AAa/sjS1/5QiwC7+jtCia6q3wC7'
    $Base64String &= 'KmcIerhDfgCkbHGmUINa1gC7ctW/FJUMQQAcgHaUq7ym0AA2NcqZIU1dNQBD0EQXwuyPAwDlMofEtEWbtABdqpuSnklUNACkF8fIh+mdbwCUVzGG79IGbQCVGU1Jy2C0nwDbOyhjzso/cwCBN/QJJrFxdABf6z99VhllzQBx5PcmjvKTcQCyYlt5Lf8WzSDOJUIgBLkA/AQAfgGdGnQnr6IELMkA5QBJRU5EAK5CYII='
    $Base64String = _WinAPI_Base64Decode($Base64String)
    If @error Then Return SetError(1, 0, 0)
    Local $tSource = DllStructCreate('byte[' & BinaryLen($Base64String) & ']')
    DllStructSetData($tSource, 1, $Base64String)
    Local $tDecompress
    _WinAPI_LZNTDecompress($tSource, $tDecompress, 962)
    If @error Then Return SetError(3, 0, 0)
    $tSource = 0
    Local Const $bString = Binary(DllStructGetData($tDecompress, 1))
    If $bSaveBinary Then
        Local Const $hFile = FileOpen($sSavePath & "\Test.png", 18)
        If @error Then Return SetError(2, 0, $bString)
        FileWrite($hFile, $bString)
        FileClose($hFile)
    EndIf
    Return $bString
EndFunc   ;==>_Base64String

Func _WinAPI_Base64Decode($sB64String)
    Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "")
    Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]")
    $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($bBuffer, 1)
EndFunc   ;==>_WinAPI_Base64Decode

Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize)
    $tOutput = DllStructCreate("byte[" & $iBufferSize & "]")
    If @error Then Return SetError(1, 0, 0)
    Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", $iBufferSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0)
    If @error Then Return SetError(2, 0, 0)
    If $aRet[0] Then Return SetError(3, $aRet[0], 0)
    Return $aRet[6]
EndFunc   ;==>_WinAPI_LZNTDecompress

It converts the image to a PNG image in the memory to put it to the clipboard afterwards.

I tested it with MS Word and it worked properly.

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

@UEZ Okay, WoW!

This does work now!
But i did not expect that it is this complicated / complex.
Thank you very much! I could not have done this alone. 😳

I was testing yesterday and i used a little program called "freeclipviewer".
I was not aware of how much stuff is created in the clipboard when you do a simple image copy.
Word for example creates a whole list of image formats in the clipboard.
And the application you paste it into, selects the best format to paste from this list.

Clipboard_Word_Image_Copy_Screenshot.png.b62d71cf8d9ef1ccd133c0edcac63c1e.png

Link to comment
Share on other sites

Hello Forum,

Since my next problem seems to be related to the previous PNG Clipboard Problem i will continue here.
Everything works nice so far. The PNG is created from the Base64String and placed properly into the clipboard thanks to @UEZ

But for some unknown reason the pasting into word gives me a crash here:

$oWord.Selection.PasteSpecial(Default, False, Default, False, $iDataType, Default, Default) ; <<<<< $oWord.Selection^ ERROR

When i comment out the Clipboard PNG Logo generation herem then it does not throw an error and the image gets pasted correctly into word:

LogoToClipboard() ; <<<<<<<< When PNG ALREADY in Clipboard COMMENT OUT and Run again = No error and Image gets pasted as expected...



Here is the minimalized code of the whole script:

#include <Word.au3>
#include "WordConstants.au3"
#include <GDIPlus.au3>
#include <Clipboard.au3>

Global $oWord = _Word_Create()     ;                                            Start Word > Word.Application object
Global $oDoc = _Word_DocAdd($oWord)     ;                                       Create Document > document object
Global $oSel, $oRange, $oShape, $oInlineShape
Global $iDataType = 15 ; PNG
Global Const $wdAlignParagraphCenter = 1 ;                                      Align Center

LogoToClipboard() ; <<<<<<<< When PNG ALREADY in Clipboard COMMENT OUT and Run again = No error and Image gets pasted as expected...

$oWord.ActiveDocument.Range.Select
$oWord.Selection.Collapse($wdCollapseStart)
$oWord.Selection.PasteSpecial(Default, False, Default, False, $iDataType, Default, Default) ; <<<<< $oWord.Selection^ ERROR
$oWord.Selection.ParagraphFormat.Alignment = $wdAlignParagraphCenter


Func LogoToClipboard()

    _GDIPlus_Startup() ;                                                            Initialize Microsoft Windows GDI+
    Local $hBitmapGDI = _GDIPlus_BitmapCreateFromMemory(_Base64String()) ;          _Base64String
    Local $bPNG = _GDIPlus_StreamImage2BinaryString($hBitmapGDI) ;                  Binary String
    Local $iFormat_PNG = _ClipBoard_RegisterFormat("PNG") ;                         Registers a new clipboard format
    _ClipBoard_Open(0) ;                                                            Opens the clipboard and prevents other applications from modifying the clipboard (0 = current task)
    _ClipBoard_Empty() ;                                                            Empties the clipboard and frees handles to data in the clipboard

    Local $iSize = BinaryLen($bPNG) ;                                               Returns the number of bytes in a binary variant
    Local $hMemory = _MemGlobalAlloc($iSize, $GHND) ;                               Allocates the specified number of bytes from the heap
    Local $hLock = _MemGlobalLock($hMemory) ;                                       Locks a global memory object and returns a pointer to the first byte of the object's memory block
    Local $tData = DllStructCreate("byte png[" & $iSize & "]", $hLock) ;            Creates a C/C++ style structure to be used in DllCall
    $tData.png = Binary($bPNG) ;                                                    Returns the binary representation of an expression
    _MemGlobalUnlock($hMemory) ;                                                    Decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE
    _ClipBoard_SetDataEx($hMemory, $iFormat_PNG) ;                                  Places data on the clipboard in a specified clipboard format
    _MemGlobalFree($hMemory) ;                                                      Frees the specified global memory object and invalidates its handle

    _GDIPlus_ImageDispose($hBitmapGDI) ;                                            Release an image object
    _GDIPlus_Shutdown() ;                                                           Clean up resources used by Microsoft Windows GDI+

EndFunc   ;==>LogoToClipboard

Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "PNG", $iQuality = 80) ; Coded by UEZ 2013 build 2014-01-25
    Local $sImgCLSID, $tGUID, $tParams
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            Local $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)

    Return $bData
EndFunc   ;==>_GDIPlus_StreamImage2BinaryString

Func _Base64String($bSaveBinary = False, $sSavePath = @ScriptDir)
    Local $Base64String
    $Base64String &= 'm7MAiVBORw0KGgoAAAAADUlIRFIlAHBkARgIBgAocOIElVQAGAlwSFlzEAAACxIBDAHS3QB+/AAAA3RJRABBVHgB7ZsxbwDTUBSFDWKq1ACVSmwMwNof0ACNhQXGDsxIlQC6UcHGPwC1WwAlpM79AbCwsADxA7oCAxsSWQCROnM+iFOSWgCJRJN3bsq50gBVHDt59/g79gDzs/PSdYkQCAKBQgJ1JnCjvPgAvcMhidta+UAAeUe5Of7AT70Afld+Vp6N13UA3duDyeI6LKwAiyEbgvlU+UQA+VDJ+3lxro0AH5XvlKdK3g8ARzHD/IYMnwEAPbzbWnip3FcALjKh/87sK2YAHCtfK0ezG6sAnUE3Lwmss+IAuaR8U75Q/qsAGewN36UN2qIAzdJR0RDOCroAGi4eVzFiFjwAbdEmbVOjZFQAM4SL9Sfl4xUA0qJtalCrXFQAMgRAH5T3GlAAoga1yplS5aIAThfCUdvCDJUAmcRXLe0oR5MANf2CafRV5QwAORGH1maAnpoA1C4TFQxh5LMAymvGItjULjMA+mrfZU3fd9AAVTEcXeZoapEAAUPbz7XyrvIAouv6T7ssbvoA3GZgEBrQYg8AZ5cFhH07gQsAAWhBkzWchvBAbMoO4C/6BAagALBa2DU5DeGpAG21sGtyGcIdAHKl7qo/MNBkAL17dxnCj0tVAOO+U5jLEH7pAKsaVm0uQzarCLohXQECCvvhlQDmMoQJCVXDqgDNZQizQ6qGVQCbyxCm6lSNLwBOYS5DzrTTPABhrRZoQpstXACGsMPMm6oWdgBNTkOY/VEt7ACanIbMn1HY3gAquis0WcNpCAAAjq17P10cLQBosobTEHac6QCddghjDWixxwCt5gqmf6sedQB7h6+kgRmFzgBAw8gpoK/tPgBD0HGkfN8LMgC8UhsNJaKCIQCAeKZk0lrroAAmtctE+y5reADX6S52lUzv3AAa/sjS1/5QiwC7+jtCia6q3wC7'
    $Base64String &= 'KmcIerhDfgCkbHGmUINa1gC7ctW/FJUMQQAcgHaUq7ym0AA2NcqZIU1dNQBD0EQXwuyPAwDlMofEtEWbtABdqpuSnklUNACkF8fIh+mdbwCUVzGG79IGbQCVGU1Jy2C0nwDbOyhjzso/cwCBN/QJJrFxdABf6z99VhllzQBx5PcmjvKTcQCyYlt5Lf8WzSDOJUIgBLkA/AQAfgGdGnQnr6IELMkA5QBJRU5EAK5CYII='
    $Base64String = _WinAPI_Base64Decode($Base64String)
    If @error Then Return SetError(1, 0, 0)
    Local $tSource = DllStructCreate('byte[' & BinaryLen($Base64String) & ']')
    DllStructSetData($tSource, 1, $Base64String)
    Local $tDecompress
    _WinAPI_LZNTDecompress($tSource, $tDecompress, 962)
    If @error Then Return SetError(3, 0, 0)
    $tSource = 0
    Local Const $bString = Binary(DllStructGetData($tDecompress, 1))
    If $bSaveBinary Then
        Local Const $hFile = FileOpen($sSavePath & "\Test.png", 18)
        If @error Then Return SetError(2, 0, $bString)
        FileWrite($hFile, $bString)
        FileClose($hFile)
    EndIf
    Return $bString
EndFunc   ;==>_Base64String

Func _WinAPI_Base64Decode($sB64String)
    Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "")
    Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]")
    $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($bBuffer, 1)
EndFunc   ;==>_WinAPI_Base64Decode

Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize)
    $tOutput = DllStructCreate("byte[" & $iBufferSize & "]")
    If @error Then Return SetError(1, 0, 0)
    Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", $iBufferSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0)
    If @error Then Return SetError(2, 0, 0)
    If $aRet[0] Then Return SetError(3, $aRet[0], 0)
    Return $aRet[6]
EndFunc   ;==>_WinAPI_LZNTDecompress

The .PasteSpecial command works. But not directly after the Clipboard is generated.
I also added a Sleep(5000) already because i thought it was a timing problem. Still Error...
 

Link to comment
Share on other sites

I think that the transfer is not yet finished to the clipboard but the program moves on already.
If i use Sleep() then the transfer also stops.
So i guess i need a way to find out if the clipboard transfer is finished before moving on.
 

Link to comment
Share on other sites

OK!
I have found the issue...

_ClipBoard_Close()

Was missing 😆

Corrected version:

Func LogoToClipboard()

    _GDIPlus_Startup() ;                                                        Initialize Microsoft Windows GDI+
    Local $hBitmapGDI = _GDIPlus_BitmapCreateFromMemory(_Base64String()) ;      _Base64String
    Local $bPNG = _GDIPlus_StreamImage2BinaryString($hBitmapGDI) ;              Binary String
    Local $iFormat_PNG = _ClipBoard_RegisterFormat("PNG") ;                     Registers a new clipboard format
    _ClipBoard_Open(0) ;                                                        Opens clipboard, prevent apps modifying clipboard
    _ClipBoard_Empty() ;                                                        Empties clipboard & frees handles to data in clipboard

    Local $iSize = BinaryLen($bPNG) ;                                           Returns the number of bytes in a binary variant
    Local $hMemory = _MemGlobalAlloc($iSize, $GHND) ;                           Allocates the specified number of bytes from the heap
    Local $hLock = _MemGlobalLock($hMemory) ;                                   Lock global mem obj,return ptr to 1st byte of obj memblock
    Local $tData = DllStructCreate("byte png[" & $iSize & "]", $hLock) ;        Creates a C/C++ style structure to be used in DllCall

    $tData.png = Binary($bPNG) ;                                                Returns the binary representation of an expression
    _MemGlobalUnlock($hMemory) ;                                                Decrements lock count associated with memory object
    _ClipBoard_SetDataEx($hMemory, $iFormat_PNG) ;                              Place data on clipboard in specified clipboard format
    _ClipBoard_Close() ;                                                        <<<<<< This was missing
    _MemGlobalFree($hMemory) ;                                                  Free the specified global mem obj & invalidate handle
    _GDIPlus_ImageDispose($hBitmapGDI) ;                                        Release an image object
    _GDIPlus_Shutdown() ;                                                       Clean up resources used by Microsoft Windows GDI+

EndFunc   ;==>LogoToClipboard

 

Edited by Blaxxun
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...