Jump to content

[Solved] PixelGetColor in a background window


Recommended Posts

Hey guys,

I am working on a script to detect changes in a video stream from IP cameras. I have everything working correctly, the only problem is that PixelGetColor only works with visible windows. I have read up on posts here that touch the subject, but none that I found offer any solution

I found the which solved many of my problems, yet the background window snapshot functionality is not present either.

If someone could point me in a proper direction in solving this, I would appreaciate it.

Thanks,

tom

Edited by tomaskir
Link to comment
Share on other sites

Do you have a dedicated PC or a virtual PC to handle the cameras and your app?

Its running on a dedicated physical PC. However there are multiple apps running and I want to analize several video streams, which is why it would be really nice to be able to get pixels from windows in the background.

Link to comment
Share on other sites

I would create a virtual PC on that machine your using. Run JUST the app that controls the cameras in it. That way you will have the window active all the time.

I just saw this:

You may be able to use it but it isn't tested.

Edited by MPH
Link to comment
Share on other sites

I would create a virtual PC on that machine your using. Run JUST the app that controls the cameras in it. That way you will have the window active all the time.

I just saw this:

You may be able to use it but it isn't tested.

Currently i just connected a 2nd monitor as a temporary solution and run stuff on there. Problem is that i read stuff from 4 cameras, and having to properly position the windows etc becomes an issue (have to make sure it works after a reboot etc) So avoiding window management and all that with background reading would be perfect. I could set up VMs, but I would like a cleaner solution, so if there is one, I will try to find it.

Great find on those posts thanks! Im gonna have a look over that code.

I also found this http://www.codeproject.com/KB/cs/CapturingMinimizedwindow.aspx

This program succesfully captures background windows, and source is included, so I am currently trying to write a dll in C# based on that code that should work with DllCall().

If i manage to get it working well enough, I will make an UDF and share :)

Thanks again for the help!

Edited by tomaskir
Link to comment
Share on other sites

You could do a winlist once the app for the cameras is started and then use winmove. That way you could position the windows on the second monitor automatically.

Yes, I could manage the windows, but luckily:

Func MemoryReadPixel($x, $y, $handle)
   Local $hDC
   Local $iColor
   Local $sColor

   $hDC = _WinAPI_GetWindowDC($handle)
   $iColor = DllCall("gdi32.dll", "int", "GetPixel", "int", $hDC, "int", $x, "int", $y)
   $sColor = Hex($iColor[0], 6)
   _WinAPI_ReleaseDC($handle, $hDC)

   Return Hex("0x" & StringRight($sColor, 2) & StringMid($sColor, 3, 2) & StringLeft($sColor, 2))
EndFunc   ;==>MemoryReadPixel

Works for background windows, and is MUCH faster then PixelGetColor()

Here is a fast test script using PixelGetColor(), FFGetPixel() and MemoryReadPixel()

#include "FastFind.au3"
#include <WinAPI.au3>

Opt("PixelCoordMode", 0)

$handle = WinGetHandle("Untitled - Notepad")

if $handle = "" Then
   MsgBox(0, "", "Please open a blank notepad window.")
   Exit
EndIf

$timerHndl = TimerInit()

FFSnapShot(0, 0, 0, 0, 1, $handle)
MsgBox(0, "", "PixelGetColor color returned : " & hex(PixelGetColor(200, 200, $handle)) & @CRLF & _
                 "FFGetPixel color returned : " & Hex(FFGetPixel(200, 200, 1)) & @CRLF & _
                 "MemoryReadPixel color returned : " & MemoryReadPixel(200, 200, $handle) )

MsgBox(0, "", "PixelGetColor average speed over 100 attempts : " & test_speed_PixelGetColor($handle) & " ms" & @CRLF & _
                 "FFGetPixel average speed over 100 attempts : " & test_speed_FFGetPixel($handle) & " ms" & @CRLF & _
                 "MemoryReadPixel average speed over 100 attempts : " & test_speed_MemoryReadPixel($handle) & " ms")

Func MemoryReadPixel($x, $y, $handle)
   Local $hDC
   Local $iColor
   Local $sColor
  
   $hDC = _WinAPI_GetWindowDC($handle)
   $iColor = DllCall("gdi32.dll", "int", "GetPixel", "int", $hDC, "int", $x, "int", $y)
   $sColor = Hex($iColor[0], 6)
   _WinAPI_ReleaseDC($handle, $hDC)

   Return Hex("0x" & StringRight($sColor, 2) & StringMid($sColor, 3, 2) & StringLeft($sColor, 2))
EndFunc ;==>MemoryReadPixel

Func test_speed_MemoryReadPixel($param1)
   Local $count = 0

   For $i = 1 To 100
      $timer = TimerDiff($timerHndl)
      $color = MemoryReadPixel(200, 200, $param1)
      $timer = TimerDiff($timerHndl) - $timer

      $count += $timer
      Sleep(10)
   Next

   Return($count / 100)
EndFunc ;==>test_speed_MemoryReadPixel

Func test_speed_FFGetPixel($param1)
   Local $count = 0

   FFSnapShot(0, 0, 0, 0, 1, $param1)

   For $i = 1 To 100
      $timer = TimerDiff($timerHndl)
      $color = Hex(FFGetPixel(200, 200, 1))
      $timer = TimerDiff($timerHndl) - $timer

     $count += $timer
     Sleep(10)
   Next

   Return($count / 100)
EndFunc ;==>test_speed_FFGetPixel

Func test_speed_PixelGetColor($param1)
   Local $count = 0

   For $i = 1 To 100
      $timer = TimerDiff($timerHndl)
      $color = Hex(PixelGetColor(200, 200, $param1))
      $timer = TimerDiff($timerHndl) - $timer

      $count += $timer
      Sleep(10)
   Next

   Return($count / 100)
EndFunc ;==>test_speed_PixelGetColor

While FFGetPixel() is insanely fast, it requires its own dll, and if you need to make a new snapshot for every FFGetPixel() call, its actually quite slow.

Thank you very much for finding that post!

Edited by tomaskir
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...