Sign in to follow this  
Followers 0
Andreik

Image streaming

2 posts in this topic

I am working on a desktop remote application so I made a simple server and client to send binary screen captures from client to server. All it's good if I test both scripts on my computer but when the client is in other network many screen shots are corrupted and some of them looks good. Have any idea why?

 

Client:

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


TCPStartup()
$Client = TCPConnect(@IPAddress1,12100)

_GDIPlus_Startup()

While True
    Local $hHBitmap = _ScreenCapture_Capture('')
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    $bData = _GDIPlus_StreamImage2BinaryString($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    TCPSend($Client,'~stream:' & BinaryLen($bData))
    While BinaryLen($bData)
        $a = TCPSend($Client, $bData)
        $bData = BinaryMid($bData, $a+1, BinaryLen($bData)-$a)
    WEnd
    Sleep(10)
WEnd

TCPCloseSocket($Client)
TCPShutdown()
_GDIPlus_Shutdown()

Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 100)  ;UEZ
    Local $sImgCLSID, $tGUID, $tParams, $tData
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            $tData = DllStructCreate("int Quality")
            DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
            Local $pData = DllStructGetPtr($tData)
            $tParams = _GDIPlus_ParamInit(1)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
        Case "PNG", "BMP", "GIF", "TIF"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch
    Local $hStream = _WinAPI_CreateStreamOnHGlobal() ;http://msdn.microsoft.com/en-us/library/ms864401.aspx
    If @error Then Return SetError(2, 0, 0)
    _GDIPlus_ImageSaveToStream($hBitmap, $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams))
    If @error Then Return SetError(3, 0, 0)
    Local $hMemory = _WinAPI_GetHGlobalFromStream($hStream) ;http://msdn.microsoft.com/en-us/library/aa911736.aspx
    If @error Then Return SetError(4, 0, 0)
    Local $iMemSize = _MemGlobalSize($hMemory)
    If Not $iMemSize Then Return SetError(5, 0, 0)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    _WinAPI_ReleaseStream($hStream) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85).aspx
    _MemGlobalFree($hMemory)
    Return $bData
EndFunc   ;==>_GDIPlus_StreamImage2BinaryString

 

Server

Global $Buffer, $BufferSize
Global $Count = 0


TCPStartup()

$Server = TCPListen(@IPAddress1,12100)
If @error Then MsgBox(0,'',@error)

Do
    $Socket = TCPAccept($Server)
    Sleep(10)
Until $Socket <> -1


While True
    $Recv = TCPRecv($Socket,10240)
    If $Recv = -1 Then
        ExitLoop
    ElseIf $Recv Then
        If StringLeft($Recv,7) = '~stream' Then
            $BufferSize = StringSplit($Recv,':')[2]
            $Buffer = '0x'
            Do
                $Recv = TCPRecv($Socket,10240)
                If BinaryLen($Recv) <> 0 Then
                    $BufferSize -= BinaryLen($Recv)
                    $Buffer &= StringTrimLeft($Recv,2)
                EndIf
            Until $BufferSize = 0
            $hFile = FileOpen(@ScriptDir & '\Screen' & $Count & '.jpeg',18)
            FileWrite($hFile,$Buffer)
            FileClose($hFile)
            $Buffer = Null
            $Count += 1
        EndIf
        If $Count = 100 Then ExitLoop
    EndIf
    Sleep(10)
WEnd

TCPCloseSocket($Socket)
TCPCloseSocket($Server)
TCPShutdown()

Exit

 


When the words fail... music speaks

Share this post


Link to post
Share on other sites



I can only imagine it is a timing issue, but I am no expert, especially with Network stuff.


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

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

  • Similar Content

    • fatpig
      By fatpig
      Dear AutoIT Community.
      I am currently working on a program that will display lots of images in a scroll down GUI.
      I create the GUI based on the number of images, which works fine.
      But all images I place using GuiCtrlCreatePic above a threshold of around 32000 pixels (cant say exactly) are placed at negative locations and finally will reach 0 again
      and will then populate on top of the images placed there before.
      For $i = 1 To $Images[0] ; Get picture dimensions $hImage = _GDIPlus_ImageLoadFromFile($ImgRep & $Images[$i]) $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) _GDIPlus_ImageDispose($hImage) ; Resize & place images in GUI $Pic[$i] = GUICtrlCreatePic($ImgRep & $Images[$i], $Spacer, Round($yPos, 0), $MaxImgWidth, $MaxImgWidth * ($iY / $iX)) $yPos = $yPos + $MaxImgWidth * ($iY / $iX) + $Spacer $log = $log & "|" & $yPos $currentlut = $Images[1] Next I have found a limit at 32767 pixels for some GUI elements when googling around.
      Can someone tell me how to circumvent that?
      thanks!
      cheers
      Felix
    • comtech80
      By comtech80
      Folks,
      I have an issue I've been trying to solve for a while, I'm trying to add static routes in DHCP via a 121 route rule in Windows 2012 R2 is a brutal manual process and wanted to automate this via AutoIT.
       
      When I use the "ControlGetText" everything displays properly in the MSG box but when I try and use "ControlSetText" or "ControlSend" the values won't display in the input box but the action comes back as successful?
      Anyone able to help me with this? I'm thinking this might be an active window issue but i'm not sure.
      Here is a part of my code.
       
      $hWnd = WinWait("[TITLE:Add a Static Route]","", 10)
      WinActivate($hWnd)
      $Status = ControlSend($hWnd, "", "[CLASS:Edit; INSTANCE:4]", "192"); Does not add 192 to the text box.
      Local $sTextEdit1 = ControlGetText($hWnd, "", "[CLASS:Edit; INSTANCE:1]")
      ConsoleWrite ( "ControlSend Status: " &  $Status & @CRLF); Returns a Value of 1
      ConsoleWrite ( "ControlGetText Value Edit1: " &  $sTextEdit1 & @CRLF);
       
      Please see attachment for more info.

    • ur
      By ur
      I have a button control as below screen.

      This one I am able to suppress using below code in all the OS.
      But on server 2008, sometimes the button highlighted in the image is not getting clicked and some times it is working.
      I have cross checked the IDs when it is not working, but it is working only.
       
      $win1 = "erwin Mart Configuration" $MartConfigWindow = _WinWaitActivate1($win1,"Database Details") ControlSetText($MartConfigWindow, "", "WindowsForms10.EDIT.app.0.378734a6", $dbserver) ControlSetText($MartConfigWindow, "", "WindowsForms10.EDIT.app.0.378734a4", $dbname) ControlSetText($MartConfigWindow, "", "WindowsForms10.EDIT.app.0.378734a9", $dbuser) ControlSetText($MartConfigWindow, "", "WindowsForms10.EDIT.app.0.378734a8", $dbpassword) ;Button clicl logic $iControlClickStatus = ControlClick($MartConfigWindow, "", "[CLASS:WindowsForms10.BUTTON.app.0.378734a; INSTANCE:2]") ;If above button click fails, trying with mouse click on the control if ControlFocus($MartConfigWindow, "", "WindowsForms10.BUTTON.app.0.378734a2")=1 then ;sometimes above button fails in win server 2008,so this loop Send("{ENTER") EndIf  
      Any suggestion on how to resolve this.?
    • DeathChicken
      By DeathChicken
      If possible please add or edit the comments to explain how this works.
       
      ;includes functions from other things
      #include <GDIPlus.au3>
      #include <ScreenCapture.au3>
      ;hotkeys
      HotKeySet("{ESC}", _exit)
      HotKeySet("{F1}", _scan)
      ;global variables
      Global $win_title                    ;name of the window
      Global $area_x                        ;
      Global $area_y                        ;
      Global $area_w                       ;
      Global $area_h                        ;
      Global $cursor                         ;
      Global $rect_file                      ;
      Global $hbmpscreen              ;
      Global $i=  1043                      ;moves the rect
      Global $ii=    378                      ;moves the rect
      Global $x=1044                        ;inner rect offset
      Global $y=501                          ;inner rect offset
      Global $hbmprect                    ;image inside rect
      Global $hscreen                        ;image whole screen
                                         
      _GDIPlus_Startup()                    ;?
      ;display hotkeys on screen
      ToolTip("Press F1 to scan | Press ESC to Exit",0,0)
                                          ;infinite loop to keep prog running
      While 1
          Sleep(100)
      WEnd
      Func _scan()
      ;~ reads your screen area:
      _read()
      ;~ converts screen captured into bmp
      _convert()
      ;~ .  Loads converted bmp to be read
      _loadBMP()
      ;~ compares the bmp of your scanned screen to the actual screen that is being displayed
      _compare()
      EndFunc
                                          ;reads screen
      Func _read()
          $hscreen = _ScreenCapture_CaptureWnd("", WinGetHandle($win_title), $area_x, $area_y, $area_x + $area_w, $area_y + $area_h, $cursor)
      EndFunc
                                          ;converts screen into bmp
      Func _convert()
          _GDIPlus_BitmapCreateFromHBITMAP($hscreen)
      EndFunc
                                          ;loads converted screen
      Func _loadBMP()
      _GDIPlus_BitmapCreateFromFile($rect_file)
      EndFunc
                                          ;compares savedBMP to current screen
      Func _compare()
      ;If(                              below code                                     ) = (                   below code           ) Then
      If _GDIPlus_BitmapGetPixel($hbmpscreen, ($i + $x) - $area_x, ($ii + $y) - $area_y) = _GDIPlus_BitmapGetPixel($hbmprect, $x, $y) Then
      ;display message box titled found with a message of found
      MsgBox("","","found")
      ;if above is not correct then
      EndIf
      EndFunc
                                          ;exit func
      Func _exit()
          Exit
      EndFunc
    • GordonFreeman
      By GordonFreeman
      Hi, i searched some topics but cannot found a simple way to do that:
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 615, 438, 192, 124) GUISetState(@SW_SHOW) ; I tried this but user reported that it work in 2006, not seems work actually $filemenu = GUICtrlCreateMenu ("&File") $fileitem = GUICtrlCreateMenuitem ("Open",$filemenu) GuiCtrlSetImage($fileitem, "shell32.dll", 4) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Also tried:
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 615, 438, 192, 124) GUISetState(@SW_SHOW) $filemenu = TrayCreateMenu("&File") $fileitem = TrayCreateItem("Open",$filemenu) ;GuiCtrlSetImage($fileitem, "shell32.dll", 4) ;GuiCtrlSetImage(TrayItemGetHandle($fileitem), "shell32.dll", 4) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Well.. thanks in advance!
       
      Ok. I found this working example from Yashied. If i cannot find a simple then i will go with it
      #Include <GUIConstantsEx.au3> #Include <GUIMenu.au3> #Include <Constants.au3> #Include <WinAPI.au3> #Include <WindowsConstants.au3> Opt('MustDeclareVars', 1) Global $hMenu, $hForm, $hFile = 1000, $idNew, $idExit $hForm = GUICreate('Menu', 400, 300) $hFile = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_InsertMenuItem ($hFile, 0, ' &Favorites', $idNew) _GUICtrlMenu_InsertMenuItem ($hFile, 1, '', 0) _GUICtrlMenu_InsertMenuItem($hFile, 2, ' E&xit', $idExit) $hMenu = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_InsertMenuItem($hMenu, 0, '&File', 0, $hFile) _GUICtrlMenu_SetMenu($hForm, $hMenu) _GUICtrlMenu_SetItemBmp($hFile, 0, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @SystemDir & '\shell32.dll', 43, 16, 16)) _GUICtrlMenu_SetItemBmp($hFile, 2, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @SystemDir & '\shell32.dll', 27, 16, 16)) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func _CreateBitmapFromIcon($iBackground, $sIcon, $iIndex, $iWidth, $iHeight) Local $hDC, $hBackDC, $hBackSv, $hIcon, $hBitmap $hDC = _WinAPI_GetDC(0) $hBackDC = _WinAPI_CreateCompatibleDC($hDC) $hBitmap = _WinAPI_CreateSolidBitmap(0, $iBackground, $iWidth, $iHeight) $hBackSv = _WinAPI_SelectObject($hBackDC, $hBitmap) $hIcon = _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight) If Not @error Then _WinAPI_DrawIconEx($hBackDC, 0, 0, $hIcon, 0, 0, 0, 0, $DI_NORMAL) _WinAPI_DestroyIcon($hIcon) EndIf _WinAPI_SelectObject($hBackDC, $hBackSv) _WinAPI_ReleaseDC(0, $hDC) _WinAPI_DeleteDC($hBackDC) Return $hBitmap EndFunc ;==>_CreateBitmapFromIcon Func _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight) Local $hIcon, $tIcon = DllStructCreate('hwnd'), $tID = DllStructCreate('hwnd') Local $Ret = DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0) If (@error) Or ($Ret[0] = 0) Then Return SetError(1, 0, 0) EndIf $hIcon = DllStructGetData($tIcon, 1) If ($hIcon = Ptr(0)) Or (Not IsPtr($hIcon)) Then Return SetError(1, 0, 0) EndIf Return $hIcon EndFunc ;==>_WinAPI_PrivateExtractIcon Ok, i noticed that is a pain create submenu with _GUICtrlMenu_CreatePopup to do like in Tray, and Tray better located, then i need images/icon with Tray functions, some workaround??