Allow2010 Posted February 2, 2017 Share Posted February 2, 2017 Hello, i would like to capture a part of the screen and then display it in my gui (refreshing it every X seconds). When i capture the screen with _ScreenCapture_Capture ("",10,10,100,100) it returns a handle to the captured screen (as i understand the help file). How can i display this captured screen in my gui without saving it to a file? It is probably simple, so sorry for the dumb question :-) Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted February 2, 2017 Moderators Share Posted February 2, 2017 (edited) Edit: Just saw your "without saving to a file". See next post The very first parameter of _ScreenCapture_Capture is the filename you would like to save the image to; I don't know that you'll be . You can save to a temp file and then use that in your image. This works for me: #include <GUIConstantsEx.au3> #include <ScreenCapture.au3> _ScreenCapture_Capture(@TempDir & "\1.jpg", 1, 1, 500, 500) GUICreate("Test", 600, 600) GUICtrlCreatePic(@TempDir & "\1.jpg", 10, 10, 280, 280) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() Of course, depending on how often you're refreshing you may well run into some "blinking" issues. Edited February 2, 2017 by JLogan3o13 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted February 2, 2017 Moderators Share Posted February 2, 2017 You could do something like this with GDI+ (code shamelessly stolen from Melba): #include <GUIConstantsEx.au3> #include <ScreenCapture.au3> _GDIPlus_Startup() Local $hHBmp = _ScreenCapture_Capture("", 0, 0, 500, 500) Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) _WinAPI_DeleteObject($hHBmp) Local $hGUI = GUICreate("GDI+ test", 800, 800, -1, -1) GUISetState() Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ;cleanup resources _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() GUIDelete($hGUI) California 1 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 2, 2017 Moderators Share Posted February 2, 2017 JLogan3o13, Quote code shamelessly stolen from Melba And who shamelessly stole it from someone else (probably Malkey or UEZ)! M23 California 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Allow2010 Posted February 3, 2017 Author Share Posted February 3, 2017 Thanks a lot, i will try it and report back, I do not want to write to a temp file as this process will be called about once a second. Link to comment Share on other sites More sharing options...
Allow2010 Posted February 3, 2017 Author Share Posted February 3, 2017 (edited) Works great, thanks a lot. I never used gdiplus before...learned something new today :-) Edit: As always there is a new question: When i capture the screen every x seconds in would like to only update the gui when the picture changed. Is there a way to campare two captured images? I can not compare the handles, i need a way to compare the bmp that is referenced by the handle. Edited February 3, 2017 by Allow2010 Link to comment Share on other sites More sharing options...
UEZ Posted February 3, 2017 Share Posted February 3, 2017 You can try this example to compare two bitmaps bitwise: 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Allow2010 Posted February 4, 2017 Author Share Posted February 4, 2017 Thank you, this works (needs <AssembleIt.au3> and fasm). But as soon as i try to move the gui it is reduced to a very small gui (from 600x600 to aprox 20x600). It is hard to explain, maybe you can try it. This bug happends even if i do not use any assembleit function. Including the <AssembleIt.au3> triggers the bug, because <AssembleIt.au3> calls a FasmInit() when included... i do not know how to fix this as the <AssembleIt.au3> is a bit to complex for me. Can you help here? expandcollapse popup#include <AssembleIt.au3> #include <ScreenCapture.au3> #include <GUIConstantsEx.au3> $hGraphics = "" $hBitmap = "" $hBitmaplast = "" $hHBmp = "" $hHBmplast = "" _GDIPlus_Startup() Local $hGUI = GUICreate("TestGUI", 600, 600, -1, -1) GUISetState() RefreshImage() AdlibRegister(RefreshImage, 500) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ;cleanup resources _WinAPI_DeleteObject($hHBmp) _WinAPI_DeleteObject($hHBmplast) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_BitmapDispose($hBitmaplast) _GDIPlus_Shutdown() GUIDelete($hGUI) Func RefreshImageMini() _GDIPlus_GraphicsDrawImage(_GDIPlus_GraphicsCreateFromHWND($hGUI), _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture("", 0, 0, 500, 500)), 0, 0) EndFunc ;==>RefreshImageMini Func RefreshImageStandard() $hHBmp = _ScreenCapture_Capture("", 0, 0, 500, 500) $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) EndFunc ;==>RefreshImageStandard Func RefreshImage() $hHBmp = _ScreenCapture_Capture("", 0, 0, 500, 500) $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) If _ASM_BitCompareBitmapsMMX($hBitmap, $hBitmaplast) = 0 Then $hBitmaplast = $hBitmap $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ConsoleWrite("change" & @CRLF) Else ConsoleWrite("no change" & @CRLF) EndIf EndFunc ;==>RefreshImage Func _ASM_BitCompareBitmapsMMX($hBitmap1, $hBitmap2) If $hBitmap1<>"" and $hBitmap2<>"" then Local $aDim1 = _GDIPlus_ImageGetDimension($hBitmap1) Local $aDim2 = _GDIPlus_ImageGetDimension($hBitmap2) If BitOR($aDim1[0] <> $aDim2[0], $aDim1[1] <> $aDim2[1]) Then Return False Local $tBitmapData1 = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $aDim1[0], $aDim1[1], $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $pScan1 = $tBitmapData1.Scan0 Local $iStride1 = $tBitmapData1.Stride * 4 Local $tPixelData1 = DllStructCreate("dword[" & Abs($iStride1 * $aDim1[1]) & "]", $pScan1) Local $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $aDim2[0], $aDim2[1], $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $pScan2 = $tBitmapData2.Scan0 Local $tPixelData2 = DllStructCreate("dword[" & Abs($iStride1 * $aDim1[1]) & "]", $pScan2) Local $tCodeBuffer = DllStructCreate("byte ASM[55]") ;reserve memory for ASM opcodes $tCodeBuffer.ASM = "0x8B7424048B7C24088B4C240CB801000000F30F6F0EF30F6F17660FEFCA660F3817C9750D83C61083C71083E90477E2EB05B800000000C3" ;~ Local $fTimer = TimerInit() ;~ Local $iRet = _AssembleIt("uint", "_BitCompareMMX", "ptr", DllStructGetPtr($tPixelData1), "ptr", DllStructGetPtr($tPixelData2), "int", $aDim1[0] * $aDim1[1]) Local $aRet = DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), _ "ptr", DllStructGetPtr($tPixelData1), _ "ptr", DllStructGetPtr($tPixelData2), _ "uint", $aDim1[0] * $aDim1[1], _ "int", Null) ;~ Local $fTimer_End = TimerDiff($fTimer) ;~ ConsoleWrite("Runtime ASM only: " & $fTimer_End & " ms" & @CRLF) _GDIPlus_BitmapUnlockBits($hBitmap1, $tBitmapData1) _GDIPlus_BitmapUnlockBits($hBitmap2, $tBitmapData2) ;~ Return $iRet Return $aRet[0] Else SetError(1) Return 0 EndIf EndFunc ;==>_ASM_BitCompareBitmapsMMX Func _BitCompareMMX() _("use32") ;32Bit! ;~ _("org " & FasmGetBasePtr($Fasm)) ;needed for assembleit debugger _("mov esi, dword[esp+4]") ;points to beginning of the bitmap1 in the memory (scan0) _("mov edi, dword[esp+8]") ;points to beginning of the bitmap2 in the memory (scan0) _("mov ecx, dword[esp+12]") ;amount of pixels to read (width * height) _("mov eax, 1") ;eax it the return value -> 1 = equal, 0 = not equal _("_loop1:") _("movdqu xmm1, [esi]") ;copy 4 byte to xmm1 register (128 bit) from bitmap1 _("movdqu xmm2, [edi]") ;copy 4 byte to xmm1 register (128 bit) from bitmap2 _("pxor xmm1, xmm2") ;xmm1 xor xmm2 -> 0xor0 and 1xor1 = 0, otherwise 1 _("ptest xmm1, xmm1") ;PTEST set the ZF flag if all bits in the result are 0 of the bitwise AND of the first source operand (first operand) and the second source operand (second operand). _("jnz _NotEqual") ;xmm1 <> xmm2 because zero flag not set _("add esi, 16") ;get next 4 pixels from bitmap1 _("add edi, 16") ;get next 4 pixels from bitmap2 _("sub ecx, 4") ;decrease pixel count by 4 -> 4 pixel will be read at once _("ja _loop1") ;exit loop when all pixels were read _("jmp _End") _("_NotEqual:") _("mov eax, 0") ;set return value to 0 _("_End:") _("ret") ;return eax EndFunc ;==>_BitCompareMMX Link to comment Share on other sites More sharing options...
Allow2010 Posted February 4, 2017 Author Share Posted February 4, 2017 (edited) OK here are two screenshot. The first one shows the gui when the script is started. Everything is fine. the second one shows the gui after i moved the window, now the gui ist resized (automatically) and only shows a small area of the screenshot. This is caused by including #include <AssembleIt.au3> Using something like WinMove("TestGUI","",100,100,900,900) somewhere in the script has the same effect, the window is not moved an it is resized as show in the second screenshot... Edited February 4, 2017 by Allow2010 Link to comment Share on other sites More sharing options...
UEZ Posted February 4, 2017 Share Posted February 4, 2017 @Allow2010 your GDI+ code produces memory leaks! Try this instead: expandcollapse popup#include <ScreenCapture.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $hGraphics = 0 $hBitmap = 0 $hBitmaplast = 0 $hHBmp = 0 $hHBmplast = 0 _GDIPlus_Startup() Local $hGUI = GUICreate("TestGUI", 500, 500, @DesktopWidth - 550, -1, -1, $WS_EX_TOPMOST) GUISetState() $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hHBmp = _ScreenCapture_Capture("", 0, 0, 499, 499) $hBitmaplast = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) _WinAPI_DeleteObject($hHBmp) RefreshImage() AdlibRegister(RefreshImage, 250) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ;cleanup resources _WinAPI_DeleteObject($hHBmp) _WinAPI_DeleteObject($hHBmplast) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_BitmapDispose($hBitmaplast) _GDIPlus_Shutdown() GUIDelete($hGUI) Func RefreshImage() If $hHBmp Then _WinAPI_DeleteObject($hHBmp) $hHBmp = _ScreenCapture_Capture("", 0, 0, 499, 499) If $hBitmap Then _GDIPlus_ImageDispose($hBitmap) $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) $iCompare = _ASM_BitCompareBitmapsMMX($hBitmap, $hBitmaplast) Switch $iCompare Case 0 If $hBitmaplast Then _GDIPlus_ImageDispose($hBitmaplast) $hBitmaplast = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, 500, 500, $GDIP_PXF24RGB) ConsoleWrite("change" & @CRLF) Case 1 ConsoleWrite("no change" & @CRLF) EndSwitch EndFunc ;==>RefreshImage Func _ASM_BitCompareBitmapsMMX($hBitmap1, $hBitmap2) Local $aDim1 = _GDIPlus_ImageGetDimension($hBitmap1) If @error Then Return SetError(1, 0, -1) Local $aDim2 = _GDIPlus_ImageGetDimension($hBitmap2) If @error Then Return SetError(2, 0, -1) If BitOR($aDim1[0] <> $aDim2[0], $aDim1[1] <> $aDim2[1]) Then Return 1 Local $tBitmapData1 = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $aDim1[0], $aDim1[1], $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $pScan1 = $tBitmapData1.Scan0 Local $iStride1 = $tBitmapData1.Stride * 4 Local $tPixelData1 = DllStructCreate("dword[" & Abs($iStride1 * $aDim1[1]) & "]", $pScan1) Local $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $aDim2[0], $aDim2[1], $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $pScan2 = $tBitmapData2.Scan0 Local $tPixelData2 = DllStructCreate("dword[" & Abs($iStride1 * $aDim1[1]) & "]", $pScan2) Local $tCodeBuffer = DllStructCreate("byte ASM[55]") ;reserve memory for ASM opcodes $tCodeBuffer.ASM = "0x8B7424048B7C24088B4C240CB801000000F30F6F0EF30F6F17660FEFCA660F3817C9750D83C61083C71083E90477E2EB05B800000000C3" ;write opcodes into memory (struct) / length: 55 Local $aRet = DllCall("user32.dll", "boolean", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), _ "struct*", $tPixelData1, _ "struct*", $tPixelData2, _ "uint", $aDim1[0] * $aDim1[1], _ "int", Null) _GDIPlus_BitmapUnlockBits($hBitmap1, $tBitmapData1) _GDIPlus_BitmapUnlockBits($hBitmap2, $tBitmapData2) Return $aRet[0] EndFunc ;==>_ASM_BitCompareBitmapsMMX California 1 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Allow2010 Posted February 5, 2017 Author Share Posted February 5, 2017 Thanks a lot !!! Link to comment Share on other sites More sharing options...
California Posted April 18, 2018 Share Posted April 18, 2018 Thanks to everyone who replied in this thread I was able to realize my long-awaited solution Simplified snippet: #include <GUIConstantsEx.au3> #include <ScreenCapture.au3> Global $g_hGUI = GUICreate("GDI+ test 2", 600, 600, -1, -1) GUISetState(@SW_SHOW, $g_hGUI) _GDIPlus_Startup() Global $g_hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) OnAutoItExitRegister("CleanupResources") Local $tDelta = TimerInit() Do If TimerDiff($tDelta) >= 67 Then ; => 30 FPS $tDelta = TimerInit() RefreshImage() EndIf Until GUIGetMsg() == $GUI_EVENT_CLOSE Func RefreshImage() Local $hHBmp = _ScreenCapture_Capture("", 0, 0, 500, 500) Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) _GDIPlus_GraphicsDrawImage($g_hGraphics, $hBitmap, 50, 50) _WinAPI_DeleteObject($hHBmp) _GDIPlus_BitmapDispose($hBitmap) EndFunc Func CleanupResources() _GDIPlus_GraphicsDispose($g_hGraphics) _GDIPlus_Shutdown() GUIDelete($g_hGUI) EndFunc Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now