Jump to content

Get Binary image from clipboard


Recommended Posts

I'm trying to get the binary of an image saved in the clipboard but with no results, here is my script:

it creates an hidden IE window, goes on Autoit webpage, copy an image, and displays it in a GUI (to prove there is an image in the clipboard), then Im trying to get the binary but returns 0

#include <IE.au3>
#include <Clipboard.au3>
#include <GDIPlus.au3>
#Include <Memory.au3>
$oIE = _IECreate('http://www.autoitscript.com/', 0, 0)
$oImg = _IEImgGetCollection($oIE, 4)
$oRange = $oIE.document.Body.CreateControlRange()
$oRange.Add($oImg)
$oRange.ExecCommand('Copy')

$hImage = _ClipBoard_GetData($CF_BITMAP)
$hBinaryBitmap = _ClipBoard_GetData($CF_DIB)

_GDIPlus_Startup()
$oBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$nHeight = _GDIPlus_ImageGetHeight($oBitmap)
$nWidth = _GDIPlus_ImageGetWidth($oBitmap)
$Gui = GUICreate('IE Image', $nWidth, $nHeight, 250, 250)
GUISetState()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Gui)
_GDIPlus_GraphicsDrawImage($hGraphic, $oBitmap, 0, 0)

;~ ---------- this-------------
$nImageSize = _MemGlobalSize($hBinaryBitmap)
MsgBox(0, '', 'Image Size: ' & $nImageSize & ' Bytes')
ConsoleWrite($nImageSize & @CRLF)
$pImageBytes = _MemGlobalLock($hBinaryBitmap)

$sImageBuffer = DllStructCreate('byte[' & $nImageSize & ']')
$pImageBuffer = DllStructGetPtr($sImageBuffer)
_MemMoveMemory($pImageBuffer, $pImageBytes, $nImageSize)
ConsoleWrite('' & DllStructGetData($sImageBuffer, 1))
_MemGlobalUnlock($hImage)
;~ --------- this ---------------
Sleep(5000)

_GDIPlus_ImageDispose($oBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

I have highlighted the part that get the binary of the image

Link to comment
Share on other sites

Link to comment
Share on other sites

It works here :D

I did have to allow the webpage to access my clipboard though.

Cheers,

Brett

you get the correct binary of the image not 0x0??

Why don't you save the image then put it onto the clipboard?

because if I save it with the GDI+ func (_GDIPlus_ImageSaveToFile) there is a bit loss of quality
Link to comment
Share on other sites

I'm trying to get the binary of an image saved in the clipboard but with no results, here is my script:

it creates an hidden IE window, goes on Autoit webpage, copy an image, and displays it in a GUI (to prove there is an image in the clipboard), then Im trying to get the binary but returns 0

#include <IE.au3>
#include <Clipboard.au3>
#include <GDIPlus.au3>
#Include <Memory.au3>
$oIE = _IECreate('http://www.autoitscript.com/', 0, 0)
$oImg = _IEImgGetCollection($oIE, 4)
$oRange = $oIE.document.Body.CreateControlRange()
$oRange.Add($oImg)
$oRange.ExecCommand('Copy')

$hImage = _ClipBoard_GetData($CF_BITMAP)
$hBinaryBitmap = _ClipBoard_GetData($CF_DIB)

_GDIPlus_Startup()
$oBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$nHeight = _GDIPlus_ImageGetHeight($oBitmap)
$nWidth = _GDIPlus_ImageGetWidth($oBitmap)
$Gui = GUICreate('IE Image', $nWidth, $nHeight, 250, 250)
GUISetState()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Gui)
_GDIPlus_GraphicsDrawImage($hGraphic, $oBitmap, 0, 0)

;~ ---------- this-------------
$nImageSize = _MemGlobalSize($hBinaryBitmap)
MsgBox(0, '', 'Image Size: ' & $nImageSize & ' Bytes')
ConsoleWrite($nImageSize & @CRLF)
$pImageBytes = _MemGlobalLock($hBinaryBitmap)

$sImageBuffer = DllStructCreate('byte[' & $nImageSize & ']')
$pImageBuffer = DllStructGetPtr($sImageBuffer)
_MemMoveMemory($pImageBuffer, $pImageBytes, $nImageSize)
ConsoleWrite('' & DllStructGetData($sImageBuffer, 1))
_MemGlobalUnlock($hImage)
;~ --------- this ---------------
Sleep(5000)

_GDIPlus_ImageDispose($oBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

I have highlighted the part that get the binary of the image

An error with

_MemMoveMemory($pImageBuffer, $pImageBytes, $nImageSize)

should be

_MemMoveMemory($pImageBytes, $pImageBuffer, $nImageSize)

Link to comment
Share on other sites

An error with

_MemMoveMemory($pImageBuffer, $pImageBytes, $nImageSize)

should be

_MemMoveMemory($pImageBytes, $pImageBuffer, $nImageSize)

oh, that was the error, btw now Im not allocating memory but Im using the pointer supplied because with _MemMove method I get Autoit error, however now Im stuck on building the binary of the image,

here is my script:

#include <IE.au3>
#include <Clipboard.au3>
#include <GDIPlus.au3>
;~ #Include <Memory.au3>
$oIE = _IECreate('http://www.autoitscript.com/', 0, 0)
$oImg = _IEImgGetCollection($oIE, 4)
$oRange = $oIE.document.Body.CreateControlRange()
$oRange.Add($oImg)
$oRange.ExecCommand('Copy')

$hImage = _ClipBoard_GetData($CF_BITMAP)
$hBinaryBitmap = _ClipBoard_GetData($CF_DIB)

_GDIPlus_Startup()
$oBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$nHeight = _GDIPlus_ImageGetHeight($oBitmap)
$nWidth = _GDIPlus_ImageGetWidth($oBitmap)
$Gui = GUICreate('IE Image', $nWidth, $nHeight, 250, 250)
GUISetState()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Gui)
_GDIPlus_GraphicsDrawImage($hGraphic, $oBitmap, 0, 0)

;~ ------------- this -------------

$pImageBytes = _MemGlobalLock($hBinaryBitmap)
;~ MsgBox(0, '', $pImageBytes)

$sImageBuffer = DllStructCreate($tagBITMAPINFO, $pImageBytes)
$pImageBuffer = DllStructGetPtr($sImageBuffer)
MsgBox(0, '', DllStructGetData($sImageBuffer, 'RGBQuad'))
;~ $sRGBQuad = DllStructCreate('BYTE rgbBlue;' & _
;~                          'BYTE rgbGreen;' & _
;~                          'BYTE rgbRed;' & _
;~                          'BYTE rgbReserved;',)
;~ DllStructSetData($sRGBQuad,


_MemGlobalUnlock($hBinaryBitmap)
;~ ------------- this -------------
Sleep(5000)

_GDIPlus_ImageDispose($oBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

the last element of the tagBITMAPINFO struct is an array of RGBQuad structs, and Im lost here

Link to comment
Share on other sites

oh, that was the error, btw now Im not allocating memory but Im using the pointer supplied because with _MemMove method I get Autoit error, however now Im stuck on building the binary of the image,

here is my script:

#include <IE.au3>
#include <Clipboard.au3>
#include <GDIPlus.au3>
;~ #Include <Memory.au3>
$oIE = _IECreate('http://www.autoitscript.com/', 0, 0)
$oImg = _IEImgGetCollection($oIE, 4)
$oRange = $oIE.document.Body.CreateControlRange()
$oRange.Add($oImg)
$oRange.ExecCommand('Copy')

$hImage = _ClipBoard_GetData($CF_BITMAP)
$hBinaryBitmap = _ClipBoard_GetData($CF_DIB)

_GDIPlus_Startup()
$oBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$nHeight = _GDIPlus_ImageGetHeight($oBitmap)
$nWidth = _GDIPlus_ImageGetWidth($oBitmap)
$Gui = GUICreate('IE Image', $nWidth, $nHeight, 250, 250)
GUISetState()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Gui)
_GDIPlus_GraphicsDrawImage($hGraphic, $oBitmap, 0, 0)

;~ ------------- this -------------

$pImageBytes = _MemGlobalLock($hBinaryBitmap)
;~ MsgBox(0, '', $pImageBytes)

$sImageBuffer = DllStructCreate($tagBITMAPINFO, $pImageBytes)
$pImageBuffer = DllStructGetPtr($sImageBuffer)
MsgBox(0, '', DllStructGetData($sImageBuffer, 'RGBQuad'))
;~ $sRGBQuad = DllStructCreate('BYTE rgbBlue;' & _
;~                          'BYTE rgbGreen;' & _
;~                          'BYTE rgbRed;' & _
;~                          'BYTE rgbReserved;',)
;~ DllStructSetData($sRGBQuad,


_MemGlobalUnlock($hBinaryBitmap)
;~ ------------- this -------------
Sleep(5000)

_GDIPlus_ImageDispose($oBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

the last element of the tagBITMAPINFO struct is an array of RGBQuad structs, and Im lost here

What do you care about that?

If you want raw binary then do like Malkey suggested. Or even simpler:

$nImageSize = _MemGlobalSize($hBinaryBitmap)
MsgBox(0, '', 'Image Size: ' & $nImageSize & ' Bytes')
ConsoleWrite($nImageSize & @CRLF)

$pImageBytes = _MemGlobalLock($hBinaryBitmap)

$sImageBuffer = DllStructCreate('byte[' & $nImageSize & ']', $pImageBytes)

ConsoleWrite('' & DllStructGetData($sImageBuffer, 1)); to see as a string

_MemGlobalUnlock($hImage)

What exactly do you want to do? Make a bitmap file? Is that it?

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

What do you care about that?

If you want raw binary then do like Malkey suggested. Or even simpler:

$nImageSize = _MemGlobalSize($hBinaryBitmap)
MsgBox(0, '', 'Image Size: ' & $nImageSize & ' Bytes')
ConsoleWrite($nImageSize & @CRLF)

$pImageBytes = _MemGlobalLock($hBinaryBitmap)

$sImageBuffer = DllStructCreate('byte[' & $nImageSize & ']', $pImageBytes)

ConsoleWrite('' & DllStructGetData($sImageBuffer, 1)); to see as a string

_MemGlobalUnlock($hImage)

What exactly do you want to do? Make a bitmap file? Is that it?

I want to get the image as binary and write it to file.

What exactly do you want to do? Make a bitmap file? Is that it?

yes basically a bitmap file
Link to comment
Share on other sites

I want to get the image as binary and write it to file.

yes basically a bitmap file

This is copy/paste (related part) from ResourcesViewerAndCompiler.au3:

#include <IE.au3>
#include <Clipboard.au3>
#include <GDIPlus.au3>
#include <Memory.au3>
$oIE = _IECreate('http://www.autoitscript.com/', 0, 0)
$oImg = _IEImgGetCollection($oIE, 4)
$oRange = $oIE.document.Body.CreateControlRange()
$oRange.Add($oImg)
$oRange.ExecCommand('Copy')

$hImage = _ClipBoard_GetData($CF_BITMAP)
$hBinaryBitmap = _ClipBoard_GetData($CF_DIB)

_GDIPlus_Startup()
$oBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$nHeight = _GDIPlus_ImageGetHeight($oBitmap)
$nWidth = _GDIPlus_ImageGetWidth($oBitmap)
$Gui = GUICreate('IE Image', $nWidth, $nHeight, 250, 250)
GUISetState()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Gui)
_GDIPlus_GraphicsDrawImage($hGraphic, $oBitmap, 0, 0)

;~ ---------- this-------------

$iImageSize = _MemGlobalSize($hBinaryBitmap)
MsgBox(0, '', 'Image Size: ' & $iImageSize & ' Bytes')
ConsoleWrite($iImageSize & @CRLF)

$pImageBytes = _MemGlobalLock($hBinaryBitmap)

Local $tBinary = DllStructCreate("byte[" & $iImageSize & "]", $pImageBytes)
Local $bBinary = DllStructGetData($tBinary, 1)
_MemGlobalUnlock($hImage)


;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Local $tBitmap = DllStructCreate("dword HeaderSize", DllStructGetPtr($tBinary))

Local $iHeaderSize = DllStructGetData($tBitmap, "HeaderSize")

Local $iMultiplier

Switch $iHeaderSize
    Case 40
        $tBitmap = DllStructCreate("dword HeaderSize;" & _
                "dword Width;" & _
                "dword Height;" & _
                "ushort Planes;" & _
                "ushort BitPerPixel;" & _
                "dword CompressionMethod;" & _
                "dword Size;" & _
                "dword Hresolution;" & _
                "dword Vresolution;" & _
                "dword Colors;" & _
                "dword ImportantColors", _
                DllStructGetPtr($tBinary))
        $iMultiplier = 4
    Case 12
        $tBitmap = DllStructCreate("dword HeaderSize;" & _
                "ushort Width;" & _
                "ushort Height;" & _
                "ushort Planes;" & _
                "ushort BitPerPixel", _
                DllStructGetPtr($tBinary))
        $iMultiplier = 3
    Case Else
    ; Return error
EndSwitch

Local $iExponent = DllStructGetData($tBitmap, "BitPerPixel")

Local $tDIB = DllStructCreate("align 2;byte Identifier[2];" & _
        "dword BitmapSize;" & _
        "short;" & _
        "short;" & _
        "dword BitmapOffset;" & _
        "byte Body[" & $iImageSize & "]")

DllStructSetData($tDIB, "Identifier", Binary("BM"))
DllStructSetData($tDIB, "BitmapSize", $iImageSize + 14)

Local $iRawBitmapSize = DllStructGetData($tBitmap, "Size")

If $iRawBitmapSize Then
    DllStructSetData($tDIB, "BitmapOffset", $iImageSize - $iRawBitmapSize + 14)
Else
    If $iExponent = 24 Then
        DllStructSetData($tDIB, "BitmapOffset", $iHeaderSize + 14)
    Else
        Local $iWidth = DllStructGetData($tBitmap, "Width")
        Local $iHeight = DllStructGetData($tBitmap, "Height")
        $iRawBitmapSize = 4 * Floor(($iWidth * $iExponent + 31) / 32) * $iHeight + 2

        Local $iOffset_1 = $iImageSize - $iRawBitmapSize + 14
        Local $iOffset_2 = 2 ^ $iExponent * $iMultiplier + $iHeaderSize + 14

        If $iOffset_2 - $iOffset_1 - 2 <= 0 Then
            DllStructSetData($tDIB, "BitmapOffset", $iOffset_2)
        Else
            DllStructSetData($tDIB, "BitmapOffset", $iOffset_1)
        EndIf

    EndIf
EndIf

DllStructSetData($tDIB, "Body", $bBinary)

Local $tBinaryBMP = DllStructCreate("byte[" & DllStructGetSize($tDIB) & "]", DllStructGetPtr($tDIB))

Local $bBinaryToWrite = DllStructGetData($tBinaryBMP, 1)

Local $hSaveFile = FileOpen(@ScriptDir & "\ThatBitmap.bmp", 26)
FileWrite($hSaveFile, $bBinaryToWrite)
FileClose($hSaveFile)

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Sleep(5000)

_GDIPlus_ImageDispose($oBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

See if that's it?

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

It appears the output from the corrected first post script can be saved as a .bmp image file, if the appropriate extra 14 bytes are added to the existing 40 byte header section at the beginning output bitmap data.

;
#include <IE.au3>
#include <Clipboard.au3>
#include <GDIPlus.au3>
#include <Memory.au3>
$oIE = _IECreate('http://www.autoitscript.com/', 0, 0)

$oImg = _IEImgGetCollection($oIE, 4)
$oRange = $oIE.document.Body.CreateControlRange()
$oRange.Add($oImg)
$oRange.ExecCommand('Copy')

$hImage = _ClipBoard_GetData($CF_BITMAP)
$hBinaryBitmap = _ClipBoard_GetData($CF_DIB)

_GDIPlus_Startup()
$oBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hImage)
$nHeight = _GDIPlus_ImageGetHeight($oBitmap)
$nWidth = _GDIPlus_ImageGetWidth($oBitmap)
$Gui = GUICreate('IE Image', $nWidth, $nHeight, 250, 250)
GUISetState()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Gui)
_GDIPlus_GraphicsDrawImage($hGraphic, $oBitmap, 0, 0)

;~ ---------- this-------------
$nImageSize = _MemGlobalSize($hBinaryBitmap)
MsgBox(0, '', 'Image Size: ' & $nImageSize & ' Bytes')
ConsoleWrite($nImageSize & @CRLF)
$pImageBytes = _MemGlobalLock($hBinaryBitmap)

; 2 bytes "BM" & 4 bytes image size & 4 bytes reserved "00000000" &
; 4 bytes "36000000"  containing 54, standard size of header (offset to pixel data) = 14 bytes total
Local $str = Binary("BM") & StringTrimLeft(Binary($nImageSize + 14), 2) & "0000000036000000"

;ConsoleWrite("$str " & $str & @CRLF)
$sImageBuffer = DllStructCreate('byte[' & $nImageSize & ']')
$pImageBuffer = DllStructGetPtr($sImageBuffer)
_MemMoveMemory($pImageBytes, $pImageBuffer, $nImageSize)
;ConsoleWrite('' & DllStructGetData($sImageBuffer, 1))
_MemGlobalUnlock($hImage)
;~ --------- this ---------------

$bBinaryToWrite = $str & StringTrimLeft(DllStructGetData($sImageBuffer, 1), 2)
Local $hSaveFile = FileOpen(@ScriptDir & "\TheBitmap.bmp", 26)
FileWrite($hSaveFile, $bBinaryToWrite)
FileClose($hSaveFile)

Sleep(5000)

_GDIPlus_ImageDispose($oBitmap)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
;
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...