Jump to content

Updating an image control from memory?


Recommended Posts

Hello all, I am sure I have looked through the forums and none seem to exactly address my problem.

What I am basically trying to do is capture the binary data from one image control, and then set another image control to the same image(using the binary data) withotu writing it to file.

I am currently attempting to add video/webcam streaming to an instant messenger program I am working on, and my currently stumbling block is 1)how do I get the binary data from the source image control, and how to I then inject that data directly into another image control?

Thanks for any tips and advice, I will of course continue to look for an answer myself, and if I find it post it here for others.

Link to comment
Share on other sites

you cannot read binary data from a picture without the file. the only thing you could read out would be pixelgetcolor. you can't even tell the picture format or the color palette. it's all in the file, not in the pic.

all i could imagine would be a screenshot solution.

Edited by Edano

[color=rgb(255,0,0);][font="'comic sans ms', cursive;"]FukuLeaks[/color][/font]

Link to comment
Share on other sites

Hi,

Take a look at >this (there are many examples based on the same trick).

Or you can do it with GDIPlus (take a look at my IP Cam (link in my signature)).

Br, FireFox.

This is a solution I was looking for, I believe to have seen in the past, somewhere on this forum, that can convert an image control into binary data using GDI+, but have sence been unable to re-locate it, I will take a look at your IP cam and see what I glean from it. Thanks for your quick response.

Link to comment
Share on other sites

Hi,

Take a look at >this (there are many examples based on the same trick).

Or you can do it with GDIPlus (take a look at my IP Cam (link in my signature)).

Br, FireFox.

.

yes, but he does not get the data from a pic control.

[color=rgb(255,0,0);][font="'comic sans ms', cursive;"]FukuLeaks[/color][/font]

Link to comment
Share on other sites

.

yes, but he does not get the data from a pic control.

Yes this method seems to solve half of my problem, which is loading the binary directly into an image control.

Now I just need a solution to create the binary FROM an image control directly (although I have doubts about finding an answer for this, as I have looked at every webcam example on the forums, and they all seem to require that the captured image data be saved in a file before it can be displayed in the image control.)

But of course I could be pleasantly surprised, so I will wait and see, thanks for the quick responses guys!

Link to comment
Share on other sites

You can read from one window DC and write to another with BitBlts, and maybe even the same DC using some of the DLLCall's you see in _ScreenCapture_Capture.  However the image would need to be redrawn if the window is obstructed or moved offscreen.  There's a way to 'set' images into a control or window using SendMessage too, but I believe the bitmap handle needs to be maintained..

Link to comment
Share on other sites

you can't definitely get the binary from a pic control. you may get a DC and a hbitmap handle on some obscure ways, which i doubt. I've never seen that.

i only see 2 kindergarten methods:

1.  scissor and glue method:  get the position of the control, "cut" it out of a screenshot and "glue" it into your control.

2.  crayon method: get every pixelcolor and paint it pixelwise into your control.

:) E

[color=rgb(255,0,0);][font="'comic sans ms', cursive;"]FukuLeaks[/color][/font]

Link to comment
Share on other sites

you can't definitely get the binary from a pic control. you may get a DC and a hbitmap handle on some obscure ways, which i doubt. I've never seen that.

Are you so certain?  Take a peek at GetDIBits, and an older API GetBitmapBits.  There might be some GDI+ ones as well..

Link to comment
Share on other sites

Edano, thats the format of a BMP file, not a Device Independent Bitmap. To put this matter clearly to rest - yes, you can get the bits of an image for any window or control (and controls are windows).

Look at Capturing an Image to see how one would go about grabbing the data from a window/control, and then convert that into a BMP file.  Yep, there is a difference.

Link to comment
Share on other sites

I'm not sure why I needed to put negative numbers for the BitBlt here, as it should be relative to the window DC, but I just threw this together quickly to show an example, without a need to even create a DIB bitmap:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

GUIBlitExample()

Func GUIBlitExample()
    Local $hGUI = GUICreate("My Draw")

    Local $nGraphic = GUICtrlCreateGraphic(220, 50, 100, 100)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)
    GUISetState()

    Local $hGraphic = GUICtrlGetHandle($nGraphic)

    Local $hWinDC = _WinAPI_GetDC($hGUI)
    Local $hGraphicDC = _WinAPI_GetDC($hGraphic)
    ConsoleWrite("$hWinDC = " & $hWinDC & ", $hGraphicDC = " & $hGraphicDC & @CRLF)
    _WinAPI_BitBlt($hWinDC, -100, -50, 100, 100, $hGraphicDC, 0, 0, $SRCCOPY)
    _WinAPI_ReleaseDC($hGraphic, $hGraphicDC)
    _WinAPI_ReleaseDC($hGUI, $hWinDC)


    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
EndFunc
 
Link to comment
Share on other sites

Here's the longer way, using CompatibleDC's (DDC), CompatibleBitmaps (DDB), Device Independent Bitmaps (DIB's).  Note - the latter is not needed, however it is there to show that the binary data can be read (it is stored in $stBitmapBits).  The final transfer is done from the memory DC.  I still am unsure why the target x & y are relative to the source.. I must be missing something somewhere.

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>

GUIBlitExample2()
Func GUIBlitExample2()
    Local $iSizeX = 100, $iSizeY = 100
    Local $hGUI = GUICreate("My Draw")

    Local $nGraphic = GUICtrlCreateGraphic(220, 50, $iSizeX, $iSizeY)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)
    GUISetState()

    Local $hGraphic = GUICtrlGetHandle($nGraphic)
    Local $hSourceDC = _WinAPI_GetDC($hGraphic)

    Local $hMemoryDC  = _WinAPI_CreateCompatibleDC($hSourceDC)
    Local $hCompatBMP = _WinAPI_CreateCompatibleBitmap($hSourceDC, $iSizeX, $iSizeY)
    _WinAPI_SelectObject($hMemoryDC, $hCompatBMP)
    _WinAPI_BitBlt($hMemoryDC, 0, 0, $iSizeX, $iSizeY, $hSourceDC, 0, 0, $SRCCOPY)
    _WinAPI_ReleaseDC($hGraphic, $hSourceDC)

    Local Const $tagBITMAPINFOHEADER_Beta = "dword biSize;long biWidth;long biHeight;word biPlanes;word biBitCount;" & _
        "dword biCompression;dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant;"

    $stBitmapInfo = DllStructCreate($tagBITMAPINFOHEADER_Beta)
    DllStructSetData($stBitmapInfo, "biSize", 40)    ; DllStructGetSize(DllStructCreate($tagBITMAPINFOHEADER_Beta))
    DllStructSetData($stBitmapInfo, "biWidth", $iSizeX)
    DllStructSetData($stBitmapInfo, "biHeight", -$iSizeY)    ; without negative, it would be upside-down
    DllStructSetData($stBitmapInfo, "biPlanes", 1)
    DllStructSetData($stBitmapInfo, "biBitCount", 32)
    DllStructSetData($stBitmapInfo, "biCompression", 0)
    ; Everything else in BITMAPINFO = 0

    Local $nBitmapSize = $iSizeX * 4 * $iSizeY
    ConsoleWrite("Bitmap Size = " & $nBitmapSize & @CRLF)

    $stBitmapBits = DllStructCreate("byte Data["&$nBitmapSize&"];")

    $nScanLines = _WinAPI_GetDIBits($hMemoryDC, $hCompatBMP, 0, 100, DllStructGetPtr($stBitmapBits), DllStructGetPtr($stBitmapInfo), 0)
    ConsoleWrite("# scanlines written: " & $nScanLines & @CRLF)

    Local $hWinDC = _WinAPI_GetDC($hGUI)
    _WinAPI_BitBlt($hWinDC, -100, -50, $iSizeX, $iSizeY, $hMemoryDC, 0, 0, $SRCCOPY)
    _WinAPI_ReleaseDC($hGUI, $hWinDC)

    _WinAPI_DeleteDC($hMemoryDC)
    _WinAPI_DeleteObject($hCompatBMP)

    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
EndFunc
Link to comment
Share on other sites

I figured out what the problem with the previous examples was, although I still don't fully understand it.  Getting a DC for the window actually sets the DC top-left corner at the position of the last control that was created.  I really can't say why this is happening, but to get around this we just need to use another control and grab a DC to that.

However, I've figured out the way to actually set an image into a control, which will actually maintain the image even if the gui is moved around or obscured.  The method to do this is to create a Static Control of type SS_BITMAP.  AutoIt creates this type of control with GUICtrlCreatePic(), so we start there.  The next thing that's needed is to create the 'compatible' bitmap (DDB), fill that with the right data, and then use that bitmap in a call to SendMessage with the STM_SETIMAGE message (wParam = IMAGE_BITMAP).

Here's code that does the above.  Note that you can move the GUI all around and the picture will still remain:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>

GUIBlitExampleWithSet()
 
 
Func GUIBlitExampleWithSet()  ; Code by Ascend4nt
    Local $iSizeX = 100, $iSizeY = 100
    Local $hGUI = GUICreate("My Draw")

    Local $nGraphic = GUICtrlCreateGraphic(220, 50, $iSizeX, $iSizeY)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0)
    Local $nSSBitmapControl = GUICtrlCreatePic("", 50, 50, 100, 100)
    GUISetState()

    Local $hSSBitmapControl = GUICtrlGetHandle($nSSBitmapControl)
    Local $hGraphic = GUICtrlGetHandle($nGraphic)
    Local $hSourceDC = _WinAPI_GetDC($hGraphic)

    ConsoleWrite("Graphic Control DC = " & $hSourceDC & @CRLF)

    Local $hMemoryDC  = _WinAPI_CreateCompatibleDC($hSourceDC)
    Local $hCompatBMP = _WinAPI_CreateCompatibleBitmap($hSourceDC, $iSizeX, $iSizeY)
    Local $hOldObject = _WinAPI_SelectObject($hMemoryDC, $hCompatBMP)
    _WinAPI_BitBlt($hMemoryDC, 0, 0, $iSizeX, $iSizeY, $hSourceDC, 0, 0, $SRCCOPY)
    _WinAPI_ReleaseDC($hGraphic, $hSourceDC)

    _WinAPI_SelectObject($hMemoryDC, $hOldObject)
    ; We keep the Bitmap around so we can set it into the proper control
;~     _WinAPI_DeleteObject($hCompatBMP)
    _WinAPI_DeleteDC($hMemoryDC)

    ; STM_SETIMAGE = 0x0172, IMAGE_BITMAP = 0
    _SendMessage($hSSBitmapControl, 0x0172, 0, $hCompatBMP)

    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
    ; Delete the bitmap AFTER the GUI is closed
    _WinAPI_DeleteObject($hCompatBMP)
EndFunc

.

Link to comment
Share on other sites

Guess I sorta went off topic.

nullschritt, here's a basic solution to your original question:

The function GraphicsBlitBetweenWindows() should do what you need. Just provide a source control or window, and a destination control or window, and the coordinates and size, as in the example below.  Note that the image will not be redrawn when it is overwritten (see my previous post for 'setting' an image)

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
 
GUIBlitTest()

; ==============================================================================================
; Func GraphicsBlitBetweenWindows($hWndDest, $hWndSrc, $iXDest, $iYDest, $iWidth, $iHeight,
;                                 $iXSrc = 0, $iYSrc = 0)
;
; Copies graphics from one window or control to another at the given coordinates
;
; Author: Ascend4nt
; ==============================================================================================
Func GraphicsBlitBetweenWindows($hWndDest, $hWndSrc, $iXDest, $iYDest, $iWidth, $iHeight, $iXSrc = 0, $iYSrc = 0)
    Local $bSuccess, $hDCSrc, $hDCDest

    $hDCSrc = _WinAPI_GetDC($hWndSrc)
    If $hDCSrc = 0 Then Return SetError(-1, 0, False)
    $hDCDest = _WinAPI_GetDC($hWndDest)
    If $hDCDest = 0 Then
        _WinAPI_ReleaseDC($hWndSrc, $hDCSrc)
        Return SetError(-2,0,False)
    EndIf
    $bSuccess = _WinAPI_BitBlt($hDCDest, $iXDest, $iYDest, $iWidth, $iHeight, $hDCSrc, $iXSrc, $iYSrc, $SRCCOPY)
    _WinAPI_ReleaseDC($hWndSrc, $hDCSrc)
    _WinAPI_ReleaseDC($hWndDest, $hDCDest)
    Return $bSuccess
EndFunc


Func GUIBlitTest()
    Local $hGUISrc, $hGUIDest
    Local $nSrcControl, $nDestControl

; Source GUI
    $hGUISrc = GUICreate("Source", 200, 200, 50, 50)

    $nSrcControl = GUICtrlCreateGraphic(50, 50, 100, 100)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)

; Destination GUI
    $hGUIDest = GUICreate("Destination", 200, 200, 250, 250)
    GUISwitch($hGUIDest)
    $nDestControl = GUICtrlCreatePic("", 50, 50, 100, 100)
    GUISetState(@SW_SHOW, $hGUISrc)
    GUISetState(@SW_SHOW, $hGUIDest)

    MsgBox(0, "OK to continue", "Press OK to run the Blit")

    GraphicsBlitBetweenWindows(GUICtrlGetHandle($nDestControl), GUICtrlGetHandle($nSrcControl), 0, 0, 100, 100)

    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
    GUIDelete($hGUISrc)
    GUIDelete($hGUIDest)
EndFunc
Edited by Ascend4nt
Link to comment
Share on other sites

 

Guess I sorta went off topic.

nullschritt, here's a basic solution to your original question:

The function GraphicsBlitBetweenWindows() should do what you need. Just provide a source control or window, and a destination control or window, and the coordinates and size, as in the example below.  Note that the image will not be redrawn when it is overwritten (see my previous post for 'setting' an image)

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
 
GUIBlitTest()

; ==============================================================================================
; Func GraphicsBlitBetweenWindows($hWndDest, $hWndSrc, $iXDest, $iYDest, $iWidth, $iHeight,
;                                 $iXSrc = 0, $iYSrc = 0)
;
; Copies graphics from one window or control to another at the given coordinates
;
; Author: Ascend4nt
; ==============================================================================================
Func GraphicsBlitBetweenWindows($hWndDest, $hWndSrc, $iXDest, $iYDest, $iWidth, $iHeight, $iXSrc = 0, $iYSrc = 0)
    Local $bSuccess, $hDCSrc, $hDCDest

    $hDCSrc = _WinAPI_GetDC($hWndSrc)
    If $hDCSrc = 0 Then Return SetError(-1, 0, False)
    $hDCDest = _WinAPI_GetDC($hWndDest)
    If $hDCDest = 0 Then
        _WinAPI_ReleaseDC($hWndSrc, $hDCSrc)
        Return SetError(-2,0,False)
    EndIf
    $bSuccess = _WinAPI_BitBlt($hDCDest, $iXDest, $iYDest, $iWidth, $iHeight, $hDCSrc, $iXSrc, $iYSrc, $SRCCOPY)
    _WinAPI_ReleaseDC($hWndSrc, $hDCSrc)
    _WinAPI_ReleaseDC($hWndDest, $hDCDest)
    Return $bSuccess
EndFunc


Func GUIBlitTest()
    Local $hGUISrc, $hGUIDest
    Local $nSrcControl, $nDestControl

; Source GUI
    $hGUISrc = GUICreate("Source", 200, 200, 50, 50)

    $nSrcControl = GUICtrlCreateGraphic(50, 50, 100, 100)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)

; Destination GUI
    $hGUIDest = GUICreate("Destination", 200, 200, 250, 250)
    GUISwitch($hGUIDest)
    $nDestControl = GUICtrlCreatePic("", 50, 50, 100, 100)
    GUISetState(@SW_SHOW, $hGUISrc)
    GUISetState(@SW_SHOW, $hGUIDest)

    MsgBox(0, "OK to continue", "Press OK to run the Blit")

    GraphicsBlitBetweenWindows(GUICtrlGetHandle($nDestControl), GUICtrlGetHandle($nSrcControl), 0, 0, 100, 100)

    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
    GUIDelete($hGUISrc)
    GUIDelete($hGUIDest)
EndFunc

I'm sorry but could you split it into two seperate functions, one that gets the data of a control, and another that sets the data of a control? I'm trying to send a stream over a network.

Thanks for the help

Edited by nullschritt
Link to comment
Share on other sites

I gave you the second part so here is the first one:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

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

GUIBlitExample()

Func GUIBlitExample()
    #region GUI
    Local $hGUISrc = 0, $nSrcControl = 0

    $hGUISrc = GUICreate("Source", 200, 200, 50, 50)

    $nSrcControl = GUICtrlCreateGraphic(50, 50, 100, 100)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)

    GUISetState(@SW_SHOW, $hGUISrc)
    #endregion

    Local $hHBMP = 0

    GraphicsBlit(GUICtrlGetHandle($nSrcControl), $hHBMP)

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBMP)
    _WinAPI_DeleteObject($hHBMP)

    ; This is the binary data of your image.
    ConsoleWrite(BinaryLen(_GDIPlus_SaveImage2Binary($hBitmap, 100)) & @CrLf)

;~  _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\test.png")

    _GDIPlus_ImageDispose($hBitmap)
    _GDIPlus_Shutdown()

    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
EndFunc

Func GraphicsBlit($hWnd, ByRef $hHBMP)
    Local $hDC = 0, $tRect = 0

    $hDC = _WinAPI_GetDC($hWnd)

    $tRect = _WinAPI_GetClientRect($hWnd)

    Local $iLeft = DllStructGetData($tRect, "Left"), $iTop = DllStructGetData($tRect, "Top")
    Local $iRight = DllStructGetData($tRect, "Right"), $iBottom = DllStructGetData($tRect, "Bottom")

    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hHBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iRight - $iLeft, $iBottom - $iTop)

    _WinAPI_SelectObject($hCDC, $hHBMP)

    _WinAPI_BitBlt($hCDC, 0, 0, $iRight - $iLeft, $iBottom - $iTop, $hDDC, $iLeft, $iTop, $SRCCOPY)

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
EndFunc   ;==>GraphicsBlitBetweenWindows

Func _GDIPlus_SaveImage2Binary($hBitmap, $iQuality = 50) ;Coded by Andreik, modified by UEZ
    Local $sImgCLSID = _GDIPlus_EncodersGetCLSID("jpg")
    Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
    Local $pEncoder = DllStructGetPtr($tGUID)
    Local $tParams = _GDIPlus_ParamInit(1)
    Local $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
    Local $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    Local $pParams = DllStructGetPtr($tParams)
    Local $hStream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", True, "ptr*", 0)
    $hStream = $hStream[3]
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $hStream, "ptr", $pEncoder, "ptr", $pParams)
;~  _GDIPlus_BitmapDispose($hBitmap)
    Local $hMemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $hStream, "ptr*", 0)
    $hMemory = $hMemory[2]
    Local $iMemSize = _MemGlobalSize($hMemory)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data;ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    _MemGlobalFree($hMemory)
    Return $bData
EndFunc   ;==>__GDIPlus_SaveImage2Binary
Edit: Added indents.

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

I gave you the second part so here is the first one:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

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

GUIBlitExample()

Func GUIBlitExample()
    #region GUI
    Local $hGUISrc = 0, $nSrcControl = 0

    $hGUISrc = GUICreate("Source", 200, 200, 50, 50)

    $nSrcControl = GUICtrlCreateGraphic(50, 50, 100, 100)
    GUICtrlSetStyle(-1, $SS_NOTIFY)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0, 0xff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 50, 50, 40, 30, 270)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00ff00, 0xffffff)
    GUICtrlSetGraphic(-1, $GUI_GR_PIE, 58, 50, 40, -60, 90)

    GUISetState(@SW_SHOW, $hGUISrc)
    #endregion

    Local $hHBMP = 0

    GraphicsBlit(GUICtrlGetHandle($nSrcControl), $hHBMP)

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBMP)
    _WinAPI_DeleteObject($hHBMP)

    ; This is the binary data of your image.
    ConsoleWrite(BinaryLen(_GDIPlus_SaveImage2Binary($hBitmap, 100)) & @CrLf)

;~  _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\test.png")

    _GDIPlus_ImageDispose($hBitmap)
    _GDIPlus_Shutdown()

    While GUIGetMsg() <> $GUI_EVENT_CLOSE
        Sleep(10)
    WEnd
EndFunc

Func GraphicsBlit($hWnd, ByRef $hHBMP)
    Local $hDC = 0, $tRect = 0

    $hDC = _WinAPI_GetDC($hWnd)

    $tRect = _WinAPI_GetClientRect($hWnd)

    Local $iLeft = DllStructGetData($tRect, "Left"), $iTop = DllStructGetData($tRect, "Top")
    Local $iRight = DllStructGetData($tRect, "Right"), $iBottom = DllStructGetData($tRect, "Bottom")

    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hHBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iRight - $iLeft, $iBottom - $iTop)

    _WinAPI_SelectObject($hCDC, $hHBMP)

    _WinAPI_BitBlt($hCDC, 0, 0, $iRight - $iLeft, $iBottom - $iTop, $hDDC, $iLeft, $iTop, $SRCCOPY)

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
EndFunc   ;==>GraphicsBlitBetweenWindows

Func _GDIPlus_SaveImage2Binary($hBitmap, $iQuality = 50) ;Coded by Andreik, modified by UEZ
    Local $sImgCLSID = _GDIPlus_EncodersGetCLSID("jpg")
    Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
    Local $pEncoder = DllStructGetPtr($tGUID)
    Local $tParams = _GDIPlus_ParamInit(1)
    Local $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
    Local $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    Local $pParams = DllStructGetPtr($tParams)
    Local $hStream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", True, "ptr*", 0)
    $hStream = $hStream[3]
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $hStream, "ptr", $pEncoder, "ptr", $pParams)
;~  _GDIPlus_BitmapDispose($hBitmap)
    Local $hMemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $hStream, "ptr*", 0)
    $hMemory = $hMemory[2]
    Local $iMemSize = _MemGlobalSize($hMemory)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data;ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    _MemGlobalFree($hMemory)
    Return $bData
EndFunc   ;==>__GDIPlus_SaveImage2Binary
Edit: Added indents.

Br, FireFox.

 

Doesn't seem to work with the webcam control, unless I'[m doing it wrong

; *** Start added by AutoIt3Wrapper ***
#include <GUIConstantsEx.au3>
; *** End added by AutoIt3Wrapper ***
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstants.au3>
#include <Webcam.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

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

$gui = GUICreate("Webcam UDF Test",320,240)
_WebcamInit()
$camcontrol = _Webcam($gui,320,240,0,0)
GUISetState(@SW_SHOW)

$timer = TimerInit()
While 1
 $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then
  _WebcamStop()
  Exit
 EndIf
 Sleep(10)
 if TimerDiff($timer) > 2000 Then
        Local $hHBMP = 0

    GraphicsBlit(GUICtrlGetHandle($camcontrol[0]), $hHBMP)

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBMP)
    _WinAPI_DeleteObject($hHBMP)

    ; This is the binary data of your image.
    FileDelete(@ScriptDir&"\testing.jpg")
    FileWrite(@ScriptDir&"\testing.jpg", _GDIPlus_SaveImage2Binary($hBitmap, 60))
     $timer = TimerInit()
 EndIf

WEnd

webcam.au3

#include-once
#include <GUIConstants.au3>

;~ #####################################################
;~ ###                                               ###
;~ ###                  Webcam UDF                   ###
;~ ###                                               ###
;~ ### Functions : _WebcamInit()                     ###
;~ ###             _Webcam()                         ###
;~ ###             _WebcamStop()                     ###
;~ ###             _WebcamSnapShot()                 ###
;~ ###                                               ###
;~ ###                Made by L|M|TER                ###
;~ ### --------------------------------------------- ###
;~ ###                                               ###
;~ ###           Copyright ©2008 - L|M|TER          ###
;~ ###                                               ###
;~ #####################################################

;~ Declaring Variables

$WM_CAP_START = 0x400
$WM_CAP_UNICODE_START = $WM_CAP_START +100
$WM_CAP_PAL_SAVEA = $WM_CAP_START + 81
$WM_CAP_PAL_SAVEW = $WM_CAP_UNICODE_START + 81
$WM_CAP_UNICODE_END = $WM_CAP_PAL_SAVEW
$WM_CAP_ABORT = $WM_CAP_START + 69
$WM_CAP_DLG_VIDEOCOMPRESSION = $WM_CAP_START + 46
$WM_CAP_DLG_VIDEODISPLAY = $WM_CAP_START + 43
$WM_CAP_DLG_VIDEOFORMAT = $WM_CAP_START + 41
$WM_CAP_DLG_VIDEOSOURCE = $WM_CAP_START + 42
$WM_CAP_DRIVER_CONNECT = $WM_CAP_START + 10
$WM_CAP_DRIVER_DISCONNECT = $WM_CAP_START + 11
$WM_CAP_DRIVER_GET_CAPS = $WM_CAP_START + 14
$WM_CAP_DRIVER_GET_NAMEA = $WM_CAP_START + 12
$WM_CAP_DRIVER_GET_NAMEW = $WM_CAP_UNICODE_START + 12
$WM_CAP_DRIVER_GET_VERSIONA = $WM_CAP_START + 13
$WM_CAP_DRIVER_GET_VERSIONW = $WM_CAP_UNICODE_START + 13
$WM_CAP_EDIT_COPY = $WM_CAP_START + 30
$WM_CAP_END = $WM_CAP_UNICODE_END
$WM_CAP_FILE_ALLOCATE = $WM_CAP_START + 22
$WM_CAP_FILE_GET_CAPTURE_FILEA = $WM_CAP_START + 21
$WM_CAP_FILE_GET_CAPTURE_FILEW = $WM_CAP_UNICODE_START + 21
$WM_CAP_FILE_SAVEASA = $WM_CAP_START + 23
$WM_CAP_FILE_SAVEASW = $WM_CAP_UNICODE_START + 23
$WM_CAP_FILE_SAVEDIBA = $WM_CAP_START + 25
$WM_CAP_FILE_SAVEDIBW = $WM_CAP_UNICODE_START + 25
$WM_CAP_FILE_SET_CAPTURE_FILEA = $WM_CAP_START + 20
$WM_CAP_FILE_SET_CAPTURE_FILEW = $WM_CAP_UNICODE_START + 20
$WM_CAP_FILE_SET_INFOCHUNK = $WM_CAP_START + 24
$WM_CAP_GET_AUDIOFORMAT = $WM_CAP_START + 36
$WM_CAP_GET_CAPSTREAMPTR = $WM_CAP_START + 1
$WM_CAP_GET_MCI_DEVICEA = $WM_CAP_START + 67
$WM_CAP_GET_MCI_DEVICEW = $WM_CAP_UNICODE_START + 67
$WM_CAP_GET_SEQUENCE_SETUP = $WM_CAP_START + 65
$WM_CAP_GET_STATUS = $WM_CAP_START + 54
$WM_CAP_GET_USER_DATA = $WM_CAP_START + 8
$WM_CAP_GET_VIDEOFORMAT = $WM_CAP_START + 44
$WM_CAP_GRAB_FRAME = $WM_CAP_START + 60
$WM_CAP_GRAB_FRAME_NOSTOP = $WM_CAP_START + 61
$WM_CAP_PAL_AUTOCREATE = $WM_CAP_START + 83
$WM_CAP_PAL_MANUALCREATE = $WM_CAP_START + 84
$WM_CAP_PAL_OPENA = $WM_CAP_START + 80
$WM_CAP_PAL_OPENW = $WM_CAP_UNICODE_START + 80
$WM_CAP_PAL_PASTE = $WM_CAP_START + 82
$WM_CAP_SEQUENCE = $WM_CAP_START + 62
$WM_CAP_SEQUENCE_NOFILE = $WM_CAP_START + 63
$WM_CAP_SET_AUDIOFORMAT = $WM_CAP_START + 35
$WM_CAP_SET_CALLBACK_CAPCONTROL = $WM_CAP_START + 85
$WM_CAP_SET_CALLBACK_ERRORA = $WM_CAP_START + 2
$WM_CAP_SET_CALLBACK_ERRORW = $WM_CAP_UNICODE_START + 2
$WM_CAP_SET_CALLBACK_FRAME = $WM_CAP_START + 5
$WM_CAP_SET_CALLBACK_STATUSA = $WM_CAP_START + 3
$WM_CAP_SET_CALLBACK_STATUSW = $WM_CAP_UNICODE_START + 3
$WM_CAP_SET_CALLBACK_VIDEOSTREAM = $WM_CAP_START + 6
$WM_CAP_SET_CALLBACK_WAVESTREAM = $WM_CAP_START + 7
$WM_CAP_SET_CALLBACK_YIELD = $WM_CAP_START + 4
$WM_CAP_SET_MCI_DEVICEA = $WM_CAP_START + 66
$WM_CAP_SET_MCI_DEVICEW = $WM_CAP_UNICODE_START + 66
$WM_CAP_SET_OVERLAY = $WM_CAP_START + 51
$WM_CAP_SET_PREVIEW = $WM_CAP_START + 50
$WM_CAP_SET_PREVIEWRATE = $WM_CAP_START + 52
$WM_CAP_SET_SCALE = $WM_CAP_START + 53
$WM_CAP_SET_SCROLL = $WM_CAP_START + 55
$WM_CAP_SET_SEQUENCE_SETUP = $WM_CAP_START + 64
$WM_CAP_SET_USER_DATA = $WM_CAP_START + 9
$WM_CAP_SET_VIDEOFORMAT = $WM_CAP_START + 45
$WM_CAP_SINGLE_FRAME = $WM_CAP_START + 72
$WM_CAP_SINGLE_FRAME_CLOSE = $WM_CAP_START + 71
$WM_CAP_SINGLE_FRAME_OPEN = $WM_CAP_START + 70
$WM_CAP_STOP = $WM_CAP_START + 68
$cap = ""
$avi = ""
$user = ""
$snapfile = @ScriptDir & "\snapshot.bmp"

;~ ##########################################################
;~ Function Name : _WebcamInit()
;~ Description : Starts the webcam image capturing session
;~ Author : L|M|TER
;~ ##########################################################

Func _WebcamInit()
$avi = DllOpen("avicap32.dll")
$user = DllOpen("user32.dll")
EndFunc

;~ ##########################################################
;~ Function Name : _Webcam($gui,$h,$w,$l,$t)
;~ Description : Creates a webcam preview window
;~ Parameter(s):
;~  $gui - The gui where the webcam window should be created
;~  $h - The height of the webcam window
;~  $w - The width of the webcam window
;~  $l - The left position of the webcam window
;~  $t - The top position of the webcam window
;~ NOTE : All parameters required !
;~ Author : L|M|TER
;~ ##########################################################

Func _Webcam($gui,$w,$h,$l,$t)
$cap = DllCall($avi, "int", "capCreateCaptureWindow", "str", "cap", "int", BitOR($WS_CHILD,$WS_VISIBLE), "int", $l, "int", $t, "int", $w, "int", $h, "hwnd", $gui, "int", 1)

DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_DRIVER_CONNECT, "int", 0, "int", 0)
DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_SCALE, "int", 1, "int", 0)
DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_OVERLAY, "int", 1, "int", 0)
DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_PREVIEW, "int", 1, "int", 0)
DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_SET_PREVIEWRATE, "int", 1, "int", 0)

Return $cap
EndFunc

;~ ##########################################################
;~ Function Name : _WebcamStop()
;~ Description : Closes the webcam image capturing session
;~ Author : L|M|TER
;~ ##########################################################

Func _WebcamStop()
        DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_END, "int", 0, "int", 0)
        DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_DRIVER_DISCONNECT, "int", 0, "int", 0)
        DllClose($user)
        DllClose($avi)
EndFunc

;~ ##########################################################
;~ Function Name : _WebcamSnapShot($file)
;~ Description : Takes a snapshot
;~ Parameter(s):
;~  $file (Optional) - The path to the file where the snapshot will be saved (Default : @ScriptDir & "\snapshot.bmp")
;~ Author : L|M|TER
;~ ##########################################################

Func _WebcamSnapShot($file = $snapfile)
    DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_GRAB_FRAME_NOSTOP, "int", 0, "int", 0)
    DllCall($user, "int", "SendMessage", "hWnd", $cap[0], "int", $WM_CAP_FILE_SAVEDIBA, "int", 0, "str", $file)
EndFunc

Func GraphicsBlit($hWnd, ByRef $hHBMP)
    Local $hDC = 0, $tRect = 0

    $hDC = _WinAPI_GetDC($hWnd)

    $tRect = _WinAPI_GetClientRect($hWnd)

    Local $iLeft = DllStructGetData($tRect, "Left"), $iTop = DllStructGetData($tRect, "Top")
    Local $iRight = DllStructGetData($tRect, "Right"), $iBottom = DllStructGetData($tRect, "Bottom")

    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hHBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iRight - $iLeft, $iBottom - $iTop)

    _WinAPI_SelectObject($hCDC, $hHBMP)

    _WinAPI_BitBlt($hCDC, 0, 0, $iRight - $iLeft, $iBottom - $iTop, $hDDC, $iLeft, $iTop, $SRCCOPY)

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
EndFunc   ;==>GraphicsBlitBetweenWindows

Func _GDIPlus_SaveImage2Binary($hBitmap, $iQuality = 60) ;Coded by Andreik, modified by UEZ
    Local $sImgCLSID = _GDIPlus_EncodersGetCLSID("jpg")
    Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
    Local $pEncoder = DllStructGetPtr($tGUID)
    Local $tParams = _GDIPlus_ParamInit(1)
    Local $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
    Local $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    Local $pParams = DllStructGetPtr($tParams)
    Local $hStream = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", True, "ptr*", 0)
    $hStream = $hStream[3]
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $hStream, "ptr", $pEncoder, "ptr", $pParams)
;~  _GDIPlus_BitmapDispose($hBitmap)
    Local $hMemory = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $hStream, "ptr*", 0)
    $hMemory = $hMemory[2]
    Local $iMemSize = _MemGlobalSize($hMemory)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data;ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    _MemGlobalFree($hMemory)
    Return $bData
EndFunc   ;==>__GDIPlus_SaveImage2Binary
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...