Sign in to follow this  
Followers 0
FireFox

Convert Bitmap handle into bytes

15 posts in this topic

#1 ·  Posted (edited)

Hi,

I would like to convert the bitmap handle from the function _ScreenCapture_Capture to bytes.

Thanks for your help.

Br, Firefox.

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites



Capture the screen, save it, convert saved image to a binary string.

Or do you really need it directly from memory?

Br,

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

Share this post


Link to post
Share on other sites

Try this:

#include <GDIPlus.au3>
#include <Memory.au3>
#include <ScreenCapture.au3>

$PATH = _ScreenCapture_Capture("")
MsgBox(0,"",HBITMAP_To_Bytes($PATH))

Func HBITMAP_To_Bytes($HBITMAP)
    _GDIPlus_Startup()
    Local $BITMAP = _GDIPlus_BitmapCreateFromHBITMAP($HBITMAP)
    Local $JPG_ENCODER = _GDIPlus_EncodersGetCLSID("jpg")
    Local $TAG_ENCODER = _WinAPI_GUIDFromString($JPG_ENCODER)
    Local $PTR_ENCODER = DllStructGetPtr($TAG_ENCODER)
    Local $STREAM = DllCall("ole32.dll","uint","CreateStreamOnHGlobal","ptr",0,"bool",1,"ptr*",0)
    DllCall($ghGDIPDll,"uint","GdipSaveImageToStream","ptr",$BITMAP,"ptr",$STREAM[3],"ptr",$PTR_ENCODER,"ptr",0)
    _GDIPlus_BitmapDispose($BITMAP)
    Local $MEMORY = DllCall("ole32.dll","uint","GetHGlobalFromStream","ptr",$STREAM[3],"ptr*",0)
    Local $MEM_SIZE = _MemGlobalSize($MEMORY[2])
    Local $MEM_PTR = _MemGlobalLock($MEMORY[2])
    Local $DATA_STRUCT = DllStructCreate("byte[" & $MEM_SIZE & "]", $MEM_PTR)
    Local $DATA = DllStructGetData($DATA_STRUCT,1)
    _MemGlobalFree($MEMORY[2])
    _GDIPlus_Shutdown()
    Return $DATA
EndFunc

When the words fail... music speaks

Share this post


Link to post
Share on other sites

Cool code Andreik! :huh2:

Thanks for sharing.

Br,

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

Share this post


Link to post
Share on other sites

@UEZ

That's what I had actually but for security reasons I don't want to do that.

@Andreik

Thanks for your help it works great :huh2:

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Depending on what binary format you need, the result of _WinAPI_GetDIBits could suffice.

@Andreik: You have a memory leak since the stream is never deleted. Read the last post of _SetImageBinaryToCtrl in my signature when you want to solve it.

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Depending on what binary format you need, the result of _WinAPI_GetDIBits could suffice.

@Andreik: You have a memory leak since the stream is never deleted. Read the last post of _SetImageBinaryToCtrl in my signature when you want to solve it.

If there is a problem with his function can you give me an alternative? (e.g how to use this winapi func)

Br, FireFox.

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

@ProgAndy I`m not sure about this. MSDN said the second parameter of CreateStreamOnHGlobal() is fDeleteOnRelease and if is set as True the final release will automatically free the hGlobal parameter but I will take a look at your example maybe I am wrong.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

If there is a problem with his function can you give me an alternative? (e.g how to use this winapi func)

Br, FireFox.

You said you need a binary representation. In which form do you need it? Just the bytes of the pixels, a complete BMP or JPG file in memory, ...

His function is missing these lines to delete the Stream-object:

Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $STREAM[3], "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

You said you need a binary representation. In which form do you need it? Just the bytes of the pixels, a complete BMP or JPG file in memory, ...

His function is missing these lines to delete the Stream-object:

Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $STREAM[3], "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))

I need a complete JPG file in memory or if there is a way to just save the pixels and then set them to a picture control it will take it.

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

@ProgAndy

I got Andreik's function working and I added your 2 lines before the _MemGlobalFree func and I works as I want so for me it's solved :huh2:

Br, FireFox

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

@ProgAndy

In fact I want to "load" the binary from a modified unreadable jpg file, then edit bytes to make it readable and set it to a pic control.

I hope it's possible :huh2:

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Why use GDI+?

#Include <ScreenCapture.au3>

$hBitmap = _ScreenCapture_Capture()

$tBITMAP = DllStructCreate('long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits')
DllCall('gdi32.dll', 'int', 'GetObject', 'ptr', $hBitmap, 'int', DllStructGetSize($tBITMAP), 'ptr', DllStructGetPtr($tBITMAP))
$tBits = DllStructCreate('byte[' & DllStructGetData($tBITMAP, 'bmWidth') * DllStructGetData($tBITMAP, 'bmHeight') * DllStructGetData($tBITMAP, 'bmBitsPixel') / 8 & ']')
DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $hBitmap, 'dword', DllStructGetSize($tBits), 'ptr', DllStructGetPtr($tBits))
DllCall('gdi32.dll', 'int', 'DeleteObject', 'ptr', $hBitmap)
$bBits = DllStructGetData($tBits, 1)

ConsoleWrite(BinaryLen($bBits) & @CR)
Edited by Yashied

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

When you want to set an image to a picture control (e.g. GUICtrlCreatePic) Then you need a HBITMAP, just as it _ScreeCapture_Capture returns. (use _GUICtrlStatic_SetImage from )

If you have an unreadable JPG:

- read binary to memory

- modify it

- use the function from the link to load the jpg from memory with GDI+

- convert it to a HBITMAP

- delete the GDI+-image

- set the HBITMAP to the control

- don't delete the HBITMAP, now it belongs to the pic-control

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Here a modification of Andreik's code - now you can select the JPG save quality:

#include <Memory.au3>
#include <ScreenCapture.au3> ;includes GDIPlus.au3

_GDIPlus_Startup() ;don't forget ;-)
$HBITMAP = _ScreenCapture_Capture("", 0, 0, 100, 100)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($HBITMAP)
$s = Bitmap2BinaryString($hBitmap)
ConsoleWrite(StringLen($s) & @CRLF)
_WinAPI_DeleteObject($HBITMAP)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_ShutDown()

Exit

;GDIPlus.au3 must be included; JPG quality: 0 - 100 (worst - best)
;$hBitmap must be a GDI+ compatible bitmap format!!!
Func Bitmap2BinaryString($hBitmap, $JPEG_Quality = 90) ;code by Andreik, modified by UEZ
    Local $declared = True
    If Not $ghGDIPDll Then
        _GDIPlus_Startup()
        $declared = False
    EndIf
    Local $STREAM = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", 1, "ptr*", 0)
    $STREAM = $STREAM[3]
    Local $JPG_ENCODER = _GDIPlus_EncodersGetCLSID("JPG")
    Local $TAG_ENCODER = _WinAPI_GUIDFromString($JPG_ENCODER)
    Local $PTR_ENCODER = DllStructGetPtr($TAG_ENCODER)
    Local $tParams = _GDIPlus_ParamInit (1)
    Local $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", $JPEG_Quality)
    Local $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    Local $pParams = DllStructGetPtr($tParams)
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $STREAM, "ptr", $PTR_ENCODER, "ptr", $pParams)
    $tData = 0
    $tParams = 0
    Local $MEMORY = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $STREAM, "ptr*", 0)
    $MEMORY = $MEMORY[2]
    Local $MEM_SIZE = _MemGlobalSize($MEMORY)
    Local $MEM_PTR = _MemGlobalLock($MEMORY)
    Local $DATA_STRUCT = DllStructCreate("byte[" & $MEM_SIZE & "]", $MEM_PTR)
    Local $DATA = DllStructGetData($DATA_STRUCT, 1)
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $STREAM, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    _MemGlobalFree($MEMORY)
    If Not $declared Then _GDIPlus_Shutdown()
    Return $DATA
EndFunc

Br,

UEZ

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

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  
Followers 0