Image to Hex-String

  • Yo,

    Als ich möchte gerne einen Screenshot erstellen, allerdings nicht einfach auf der Festplatte speichern, sondern es etwas anders machen ;)
    Den Screenshot erstelle ich so (und stelle die Qualtität ein) :

    [autoit]

    #include <ScreenCapture.au3>

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func TakeScreenshot($Quality)
    Local $hImage, $Path
    $Path = @ScriptDir & "\Screenshot.jpg"
    _ScreenCapture_SetJPGQuality($Quality)
    $hImage = _ScreenCapture_Capture("")
    _ScreenCapture_SaveImage($Path, $hImage)
    EndFunc

    [/autoit]

    In diesem Fall wird der Screenshot jedoch auf der Festplatte gespeichert.
    Ich möchte ihn im Speicher in einen Hex String (Binary ,also 0x....) umwandeln und diesen mit einer Funktion returnen.
    Ein normales Bild von der HDD wandle ich folgendermaßen in einen Hex-String um:

    [autoit]

    Func ImageToHex($FilePath)
    FileWrite(@AppDataDir & "\Hex.txt",_StringToHex(BinaryToString(FileRead($FilePath))))
    EndFunc

    [/autoit]

    Wie kann ich den Screenshot weiterhin mit der gewünschten Kompression machen, allerdings anstatt den Screenshot als Bild zu speichern, direkt als Hex-String zurückgeben?
    Jede Hilfe ist willkommen:)

    Einmal editiert, zuletzt von Madara (10. Januar 2014 um 23:41)

  • Wir hatten das doch heute schon in der SB?!

    http://www.autoitscript.com/forum/topic/15…ng#entry1116225

    There's a joke that C has the speed and efficieny of assembly language combined with readability of....assembly language. In other words, it's just a glorified assembly language. - Teh Interwebz

    C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, you blow off your whole leg. - Bjarne Stroustrup
    Genie zu sein, bedeutet für mich, alles zu tun, was ich will. - Klaus Kinski

  • Der Bereich 0, 0 mit Breite und Höhe = 10 wird fotografiert und als JPG mit der Qualität 80 komprimert. Das Resultat wird als Binärstring in $bImage zurückgegeben.

    Spoiler anzeigen
    [autoit]


    ;Coded by UEZ 2013 -> This program requires AutoIt version 3.3.9.21 or higher!

    [/autoit] [autoit][/autoit] [autoit]

    #include <Screencapture.au3>
    #include <Memory.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    Global $hHBitmap = _ScreenCapture_Capture("", 0, 0, 10, 10)
    Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    Global $bImage = _GDIPlus_StreamImage2BinaryString($hBitmap)
    ConsoleWrite("Error: " & @error & @LF)
    MsgBox(0, "Binary", $bImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_Shutdown()

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = "Converted.jpg") ;coded by UEZ 2013 build 2013-09-14
    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)
    _GDIPlus_BitmapDispose($hBitmap)
    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/…3(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

    [/autoit]

    Speicherst du den Binärstring in eine Datei, so erhälst du logischerweise ein JPG Bild.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Danke für deine Antwort, UEZ.
    Allerdings meldet er das die Funktion _GDIPlus_ImageSaveToStream nicht bekannt ist, dabei habe ich GDIPlus.au3 doch included?


    [autoit]

    #include <Screencapture.au3>
    #include <Memory.au3>
    #include <WinApiEx.au3>
    #include <GDIPlus.au3>
    #include <Constants.au3>

    [/autoit]

    [autoit][/autoit][autoit]

    [s]
    [/s]

    [/autoit][autoit]

    [s]_GDIPlus_Startup()
    Global $hHBitmap = _ScreenCapture_Capture("", 0, 0, 10, 10)
    Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    Global $bImage = _GDIPlus_StreamImage2BinaryString($hBitmap)
    ConsoleWrite("Error: " & @error & @LF)
    MsgBox(0, "Binary", $bImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_Shutdown()[/s]

    [/autoit][autoit]

    [s]
    [/s]

    [/autoit][autoit]

    [s]Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = "Converted.jpg") ;coded by UEZ 2013 build 2013-09-14
    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)
    _GDIPlus_BitmapDispose($hBitmap)
    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/…3(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[/s]

    [/autoit]

    Nvm, habs :)
    Danke UEZ ! :D

    [autoit]

    #include <Screencapture.au3>
    #include <Memory.au3>
    #include <WinApiEx.au3>
    #include <GDIPlus.au3>
    #include <Constants.au3>

    [/autoit][autoit][/autoit][autoit]

    _GDIPlus_Startup()
    Global $hHBitmap = _ScreenCapture_Capture("", 0, 0, 70, 10)
    Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    Global $bImage = _GDIPlus_StreamImage2BinaryString($hBitmap)
    ConsoleWrite("Error: " & @error & @LF)
    MsgBox(0, "Binary", $bImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_Shutdown()

    [/autoit][autoit][/autoit][autoit]

    Func _GDIPlus_ImageSaveToStream($hImage, $pStream, $pEncoder, $pParams = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hImage, "ptr", $pStream, "ptr", $pEncoder, "ptr", $pParams)
    If @error Then Return SetError(1, 0, 0)
    Return SetError($aResult[0] <> 0, 0, $aResult[0] = 0)
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = "Converted.jpg") ;coded by UEZ 2013 build 2013-09-14
    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)
    _GDIPlus_BitmapDispose($hBitmap)
    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/…3(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

    [/autoit]

    Einmal editiert, zuletzt von Madara (11. Januar 2014 um 00:33)

  • This program requires AutoIt version 3.3.9.21 or higher!

    Ich nehme an, dass du noch die 3.3.8.1 oder älter benutzt. Richtig?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ja.
    Super das es jetzt funzt :)
    So kann man es übrigens von nem HexString wieder zurück in ne Datei konvertieren, falls es mal jemand brauchen sollte poste ichs hier:

    [autoit]

    #include <String.au3>

    [/autoit][autoit][/autoit][autoit]

    Func HexToImage($sData)
    FileWrite(FileOpen(@DesktopDir & "\Hex.jpg", 10), StringToBinary(_HexToString($sData)))
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    HexToImage(FileRead(@DesktopDir & "\Hex.txt"))

    [/autoit]