Jump to content

How to set image data of GUI Pic


Recommended Posts

I receive image data (jpg, bmp, raw) over TCP and would

like to display it in a GUI. It works via the filesystem but there

is obviously a delay.

Is there a way to set image data directly from an Autoit variable?

thanks

aboy

Link to comment
Share on other sites

Help button Activate .. Form of GuiCreate

;Example   From help in scite


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

Opt('MustDeclareVars', 1)

Example1()
Example2()

; example 1
Func Example1()
    Local $msg

    GUICreate("My GUI") ; will create a dialog box that when displayed is centered
    GUISetState(@SW_SHOW) ; will display an empty dialog box

    ; Run the GUI until the dialog is closed
    While 1
        $msg = GUIGetMsg()

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd
    GUIDelete()
EndFunc   ;==>Example1

; example 2
Func Example2()
    Local $gui, $background, $pic, $basti_stay, $msg
    Local $sFile = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & "\Examples\GUI\logo4.gif"
    
    $gui = GUICreate("Background", 400, 100)
    ; background picture
    $background = GUICtrlCreatePic(@SystemDir & "\oobe\images\mslogo.jpg", 0, 0, 400, 100)
    GUISetState(@SW_SHOW)

    ; transparent MDI child window
    $pic = GUICreate("", 169, 68, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $gui)
    ; transparent pic
    $basti_stay = GUICtrlCreatePic($sFile, 0, 0, 169, 68)
    GUISetState(@SW_SHOW)

    Do
        $msg = GUIGetMsg()

    Until $msg = $GUI_EVENT_CLOSE
EndFunc   ;==>Example2
[Cheeky]Comment[/Cheeky]
Link to comment
Share on other sites

Hello lordicast,

thanks for the answer but thats not quite the thing I am looking for.

Have a look at the code down there, it makes clear what my problem is.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>


Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=C:\Program Files\AutoIt-KodaGUIEditor\Forms\LiveImg.kxf
$Form1 = GUICreate("LiveImage", 770, 539, 192, 114)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "Form1Minimize")
GUISetOnEvent($GUI_EVENT_MAXIMIZE, "Form1Maximize")
GUISetOnEvent($GUI_EVENT_RESTORE, "Form1Restore")
$Pic1 = GUICtrlCreatePic("", 8, 48, 752, 480, BitOR($SS_NOTIFY,$WS_GROUP,$WS_CLIPSIBLINGS))
GUICtrlSetOnEvent(-1, "Pic1Click")
$Input1 = GUICtrlCreateInput("someserver", 16, 8, 145, 21)
GUICtrlSetOnEvent(-1, "Input1Change")
$Button1 = GUICtrlCreateButton("Connect", 232, 8, 49, 25, 0)
GUICtrlSetOnEvent(-1, "Button1Click")
$Input2 = GUICtrlCreateInput("someport", 168, 8, 57, 21)
GUICtrlSetOnEvent(-1, "Input2Change")
$Button2 = GUICtrlCreateButton("Disconnect", 288, 8, 65, 25, 0)
GUICtrlSetOnEvent(-1, "Button2Click")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###


TCPStartUp()                                    

Global $client = ""
Global $rData = Binary("")


While 1
    Sleep(100)      
WEnd

Func Button1Click() ; Connect
    $ip = GUICtrlRead( $Input1 )
    $port = GUICtrlRead( $Input2 )
    
    $client =  TCPConnect( $ip, $port)  
    $rData = TCPRecv( $client, 8192, 1)   ; the server sends the binary content of an image file: jpg, bmp or whatever is needed
    
    SetImageData( $Pic1, $rData)   ; ######## this kind of function is needed #######
EndFunc

; rest of the functions stripped...

$rdata holds the binary data of an image file but I can not set it directly to $Pic1

Up to now I have to save $rData to a file

$myFile = FileOpen( "newimage.jpg" , 2)
FileWrite( $myFile, $rData )
FileClose( $myFile )

, and then call

GUICtrlSetImage( $Pic1, "newimage.jpg" )

I would like to avoid this step, any ideas?

aboy

Link to comment
Share on other sites

I receive image data (jpg, bmp, raw) over TCP and would

like to display it in a GUI. It works via the filesystem but there

is obviously a delay.

Is there a way to set image data directly from an Autoit variable?

thanks

aboy

Try this. Unfortunately I have not had time to test it. Use _GDIPlus_BitmapCreateHBITMAPFromBitmap() to create HBitmap from your image.

func _SetHImage($controlID, $hBitmap)
    
    const $STM_SETIMAGE = 0x0172
    
    local $hWnd, $Style

    $hWnd = GUICtrlGetHandle($controlID)
    if $hWnd = 0 then
        return SetError(1, 0, 0)
    endif
    $Style = _WinAPI_GetWindowLong($hWnd, $GWL_STYLE)
    if @error then
        return SetError(1, 0, 0)
    endif
    _WinAPI_SetWindowLong($hWnd, $GWL_STYLE, BitOR($Style, Hex($SS_BITMAP)))
    if @error then
        return SetError(1, 0, 0)
    endif
    _WinAPI_DeleteObject(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, 0))
    _SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap)
    if @error then
        return SetError(1, 0, 0)
    endif
    return 1
endfunc; _SetHImage
Edited by Yashied
Link to comment
Share on other sites

...

$rdata holds the binary data of an image file but I can not set it directly to $Pic1

Up to now I have to save $rData to a file

$myFile = FileOpen( "newimage.jpg" , 2)
FileWrite( $myFile, $rData )
FileClose( $myFile )

, and then call

GUICtrlSetImage( $Pic1, "newimage.jpg" )

I would like to avoid this step, any ideas?

aboy

This is pulled out of ResourcesViewerAndCompiler.au3:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

DllOpen("gdiplus.dll") ; 'linking'

Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=C:\Program Files\AutoIt-KodaGUIEditor\Forms\LiveImg.kxf
$Form1 = GUICreate("LiveImage", 770, 539, 192, 114)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
;GUISetOnEvent($GUI_EVENT_MINIMIZE, "Form1Minimize")
;GUISetOnEvent($GUI_EVENT_MAXIMIZE, "Form1Maximize")
;GUISetOnEvent($GUI_EVENT_RESTORE, "Form1Restore")
$Pic1 = GUICtrlCreatePic("", 8, 48, 752, 480, BitOR($SS_NOTIFY, $WS_GROUP, $WS_CLIPSIBLINGS))
;GUICtrlSetOnEvent(-1, "Pic1Click")
$Input1 = GUICtrlCreateInput("someserver", 16, 8, 145, 21)
;GUICtrlSetOnEvent(-1, "Input1Change")
$Button1 = GUICtrlCreateButton("Connect", 232, 8, 49, 25, 0)
GUICtrlSetOnEvent(-1, "Button1Click")
$Input2 = GUICtrlCreateInput("someport", 168, 8, 57, 21)
;GUICtrlSetOnEvent(-1, "Input2Change")
$Button2 = GUICtrlCreateButton("Disconnect", 288, 8, 65, 25, 0)
;GUICtrlSetOnEvent(-1, "Button2Click")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###


TCPStartup()

Global $client = ""
Global $rData = Binary("")


While 1
    Sleep(100)
WEnd

Func Button1Click() ; Connect
    $ip = GUICtrlRead($Input1)
    $port = GUICtrlRead($Input2)

    $client = TCPConnect($ip, $port)
    $rData = TCPRecv($client, 8192, 1) ; the server sends the binary content of an image file: jpg, bmp or whatever is needed

    ;SetImageData( $Pic1, $rData)   ; ######## this kind of function is needed #######

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Local $iWidthGDI
    Local $iHeightGDI

    Local $hBitmap = _CreateHBitmapFromBinaryImage($rData, $iWidthGDI, $iHeightGDI)

    GUICtrlSetPos($Pic1, 8, 48, $iWidthGDI, $iHeightGDI) ; ...whatever

    Local $iHMsg = GUICtrlSendMsg($Pic1, 370, 0, $hBitmap) ; STM_SETIMAGE = 370

    If $iHMsg Then
        DllCall("gdi32.dll", "int", "DeleteObject", "hwnd", $iHMsg)
    EndIf

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

EndFunc   ;==>Button1Click

; rest of the functions stripped...


Func Form1Close()
    Exit
EndFunc   ;==>Form1Close









Func _CreateHBitmapFromBinaryImage($bBinary, ByRef $iWidth, ByRef $iHeight) ; ProgAndy's originally

    Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
    DllStructSetData($tBinary, 1, $bBinary)

    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GlobalAlloc", _  ;  local version will work too (no difference in local and global heap)
            "dword", 2, _  ; LMEM_MOVEABLE
            "dword", DllStructGetSize($tBinary))

    If @error Or Not $a_hCall[0] Then
        Return SetError(1, 0, "")
    EndIf

    Local $hMemory = $a_hCall[0]

    Local $a_pCall = DllCall("kernel32.dll", "ptr", "GlobalLock", "hwnd", $hMemory)

    If @error Or Not $a_pCall[0] Then
        DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)
        Return SetError(2, 0, "")
    EndIf

    Local $pMemory = $a_pCall[0]

    DllCall("kernel32.dll", "none", "RtlMoveMemory", _
            "ptr", $pMemory, _
            "ptr", DllStructGetPtr($tBinary), _
            "dword", DllStructGetSize($tBinary))

    DllCall("kernel32.dll", "int", "GlobalUnlock", "hwnd", $hMemory)

    Local $a_iCall = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", _
            "ptr", $pMemory, _
            "int", 1, _
            "ptr*", 0)

    If @error Or $a_iCall[0] Then
        DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)
        Return SetError(3, 0, "")
    EndIf

    Local $pStream = $a_iCall[3]

    Local $tGdiplusStartupInput = DllStructCreate("dword GdiplusVersion;" & _
            "ptr DebugEventCallback;" & _
            "int SuppressBackgroundThread;" & _
            "int SuppressExternalCodecs")

    DllStructSetData($tGdiplusStartupInput, "GdiplusVersion", 1)

    Local $a_iCall = DllCall("gdiplus.dll", "dword", "GdiplusStartup", _
            "dword*", 0, _
            "ptr", DllStructGetPtr($tGdiplusStartupInput), _
            "ptr", 0)

    If @error Or $a_iCall[0] Then
        DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)
        Return SetError(4, 0, "")
    EndIf

    Local $hGDIplus = $a_iCall[1]

    $a_iCall = DllCall("gdiplus.dll", "dword", "GdipCreateBitmapFromStream", _ ; GdipLoadImageFromStream
            "ptr", $pStream, _
            "ptr*", 0)

    If @error Or $a_iCall[0] Then
        DllCall("gdiplus.dll", "none", "GdiplusShutdown", "dword*", $hGDIplus)
        DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)
        Return SetError(5, 0, "")
    EndIf

    Local $pBitmap = $a_iCall[2]

    $a_iCall = DllCall("gdiplus.dll", "dword", "GdipGetImageDimension", _
            "ptr", $pBitmap, _
            "float*", 0, _
            "float*", 0)

    If @error Or $a_iCall[0] Then
        DllCall("gdiplus.dll", "dword", "GdipDisposeImage", "ptr", $pBitmap)
        DllCall("gdiplus.dll", "none", "GdiplusShutdown", "dword*", $hGDIplus)
        DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)
        Return SetError(5, 0, "")
    EndIf

    $iWidth = $a_iCall[2]
    $iHeight = $a_iCall[3]

    $a_iCall = DllCall("gdiplus.dll", "dword", "GdipCreateHBITMAPFromBitmap", _
            "ptr", $pBitmap, _
            "hwnd*", 0, _
            "dword", 0xFF000000)

    If @error Or $a_iCall[0] Then
        DllCall("gdiplus.dll", "dword", "GdipDisposeImage", "ptr", $pBitmap)
        DllCall("gdiplus.dll", "none", "GdiplusShutdown", "dword*", $hGDIplus)
        DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)
        Return SetError(8, 0, "")
    EndIf

    Local $hBitmap = $a_iCall[2]

    DllCall("gdiplus.dll", "dword", "GdipDisposeImage", "ptr", $pBitmap)
    DllCall("gdiplus.dll", "none", "GdiplusShutdown", "dword*", $hGDIplus)
    DllCall("kernel32.dll", "int", "GlobalFree", "hwnd", $hMemory)

    Return SetError(0, 0, $hBitmap)

EndFunc   ;==>_CreateHBitmapFromBinaryImage

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

@Yashied: there are some variables not defined in your snippet, I couldn't make it run.

@trancexx:

Your code is working, at least when I feed the content of a bitmap file into CreateHBitmapFromBinaryImage

Even greater would be if I could use the raw data that is generated on the server. It is 1 byte per pixel, gray scale,

basically the content of an binary PGM file without the header, see http://en.wikipedia.org/wiki/Portable_Gray_Map

Of course I know the width and height of the image.

Example: A 10x20 pixel image is exactly 200byte long, 1 byte per pixel.

Thanks

aboy

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...