Jump to content
Sign in to follow this  
oMBRa

Get Binary image from clipboard

Recommended Posts

oMBRa

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

Share this post


Link to post
Share on other sites
BrettF

Share this post


Link to post
Share on other sites
oMBRa

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

Share this post


Link to post
Share on other sites
Malkey

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)

Share this post


Link to post
Share on other sites
oMBRa

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

Share this post


Link to post
Share on other sites
trancexx

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

Share this post


Link to post
Share on other sites
oMBRa

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

Share this post


Link to post
Share on other sites
trancexx

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

Share this post


Link to post
Share on other sites
oMBRa

yes, perfect, where did you get those informations about bitmaps?

Share this post


Link to post
Share on other sites
trancexx

yes, perfect, where did you get those informations about bitmaps?

Different places.

Wiki about BMP file format covers a lot.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
Malkey

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()
;

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
Sign in to follow this  

×