Sign in to follow this  
Followers 0

Spooky delay in PixelGetColor?

3 posts in this topic

#1 ·  Posted (edited)

In my script i check a small area (say 20x20 pixels) with looped PixelGetColor. This has worked without any real problems for months and has taken about 20ms to complete.

To test my script, I'm running Photoshop and activate different layers to show different photos. This has also worked great. After a GPU replace (to the better) a week ago it worked great the first few days, but now I've come to a dead end.

This is the deal:

  • I open my .psd file and runs my script - performance is ok
  • I switch to layer 2 and runs my script - performance is ok
  • I switch back to layer 1 and runs my script - performance is horrible, almost 50ms.
  • At this point it doesn't matter what I do, every use of PixelGetColor() is slow.
  • Now, if I close Photoshop completely, reopens my .psd file and run the script again - performance is ok

What could possible be the problem!?

Could it be anything with the new Nvidia drivers - PhysX/hyperthreading and all that new shit (which I didnt use earlier)?

After a search through the forums I've found some interesting stuff making me far from the only one having general performance issues using the PixelGetColor() function.

I'm gonna take a shot using _GDIPlus_BitmapLockBits instead and see if that helps. But I wonder if there might be something more at work in my case?

As mentioned, I'm using the same script as I have for months. I've tested with Photoshop again and again - same result. Also tried using Paint but then its horrible speed constantly. It's just now the problems started.

Related links on the matter



GPU 1GB GeForce



Window Classic theme with all Performance Visual Effects turned off.

AutoIt v3.3.8.1

Edited by Xibalba

Share this post

Link to post
Share on other sites

I was gonna try out _GDIPlus_BitmapLockBits instead of PixelGetColor as described >here.

But my AutoIt crashes running that example, and after some debugging I have this script:

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3> ; for GDI+
Global Const $width = 600
Global Const $height = 400
Global $title = "GDI+ Test"

Opt("GUIOnEventMode", 1)
$wnd = GUICreate($title, $width, $height)
GUISetOnEvent($GUI_EVENT_CLOSE, "close")

; PixelGet method
$n1 = 100 ; set to ~100 if DWM enabled, otherwise ~100,000 (larger samples are more accurate)
$start_time = TimerInit()
For $i = 1 To $n1
    PixelGetColor( 1, 1, $wnd)
MsgBox(0, "mBox", "PixelGet avg (ms/pixel): " & $time1)

; GDI+ method
_GDIPlus_Startup ()

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($wnd)
$BitmapData = _GDIPlus_BitmapLockBits($hGraphic, 0, 0, 10, 10, $GDIP_ILMREAD, $GDIP_PXF32RGB)

$Scan0 = DllStructGetData($BitmapData, "Scan0")
$Stride = DllStructGetData($BitmapData, "Stride")
$pixel = $Scan0 + $Stride + 4

$n2 = 100000 ; 100,000
;$n2 = 1000000 ; one million iterations should take ~3 sec
For $i = 1 To $n2
    DllStructCreate("dword", $pixel)

MsgBox(0, "mBox", "GDIPlus  avg (ms/pixel):" & $time2)
MsgBox(0, "mBox", "GDIPlus = " & round($time1/$time2,1) & "x PixelGet")

_GDIPlus_BitmapUnlockBits($hGraphic, $BitmapData)
_GDIPlus_GraphicsDispose ($hGraphic)
_GDIPlus_ShutDown ()

As you can see, I've commented everything below the line $hGraphic = .

This script runs for me, but the next line is the problem.

If i move the line BitmapData = above the commented section (so it runs) AutoIt just crashes

blabla has encountered a problem and was closed, send report to Microsoft Y/N, error signature:

AppName: autoit3.exe     AppVer:     ModName: gdiplus.dll
ModVer: 5.2.6002.23084     Offset: 000464c9


Why is it crashing?

Other GDI+ examples are working for me, like >this one.

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

    • RHolmes
      By RHolmes
      I have a program that has a control that changes color a few seconds into running. So ideally, I would poll this to tell when an event has occurred. 
      I can't seem to retrieve the correct color value for a control. It always seems to return white indicating that its selecting somewhere else in the window.
      In the PixelGetColor call I'm adding half the width to the x value and subtracting half the height to the y value  in order to get the center of the control. (assuming the coords returned by ControlGetPos are top left - which i can't be sure of) But I've also tried without modifying the x/y and with changing the PixelCoordMode option to 2. Maybe I'm making a silly mistake and can't see it? Any help would be appreciated.
      Code is below:
      Opt("PixelCoordMode", 0)
      FileChangeDir( "C:\Where\My\File\Is" );
      Run( "MyProgram.exe" )
      Local $hClient = WinWaitActive( $CLIENT_TITLE, "", 10 )
      Local $systemIndicatorClassNN= "[CLASS:Qt5QWindowIcon; INSTANCE:99]"
      Local $hSystemIndicator = ControlGetHandle ( $hClient, "", $systemIndicatorClassNN)
      Local $xywh = ControlGetPos ( $hClient, "", $hSystemIndicator )
      For $i = 10 To 1 Step -1
            $color = PixelGetColor ( $xywh[0] + ($xywh[2]/2), $xywh[1] - ($xywh[3]/2), $hClient )
            LogToFile( $color )
            Sleep( 2000 )
    • Ian_Mac
      By Ian_Mac
      HotKeySet("^{SPACE}", "get_color") $colorCodeHere = ;<---------------- func get_color() Global $point = MouseGetPos() Global $color = PixelGetColor($point[0], $point[1]) MsgBox(0, "debug", "result: " & $color) EndFunc While 1 Sleep(100) WEnd Hello guys my problem is, how can i store the value that i get in that PixelGetColor($point[0], $point[0])
      i know that when i msgbox the color i will show the = of $color
      but i wanted it to be the value like  $colorCodeHere = 13456254. but  not hardcoding the value.
      or how could i say 
      if $color is = to $color then do this and if  $color is not  equal to $color then do that.
    • Fenzik
      By Fenzik
      my question is based on topic about Nvda Screen reader development atThis Link
      Autoit GUI is totaly nice for blind users, because it's controls are mostly standart.
      But in cooperation with Screen Readers this guis are much slower than other guis.
      Do you have any idea about reason of this behaviour?
      Thanks a lot for any answer.
    • Triblade
      By Triblade
      Hi all,
      I was pondering over a question with regards to the speeds of reading something and did not see this kind of question in a forum search.
      The question: What is (technically) faster? Multiple reads from the same 3d array cell, or only once make a 'temp' variable from that cell and read the value from this? I don't know if either has any real impact at all anyway, but just wanted to ask anyway. :-)
      There may be a difference if the value holds an integer or a string (or something else) but in my case, is a simple integer.
      To hopefully clarify with a small bit of code:
      $process = $start - 15 If $xy[$process][3] <> "x" Then If _ArraySearch($open, $process, 1, $open[0][0], 0, 0, 1, 1) <> -1 Then UpdateOpen($xy[$process][5], $closed[0][0]) ElseIf $start > 0 And _ArraySearch($closed, $process, 1, $closed[0][0], 0, 0, 1, 0) = -1 Then Add_open($start, $closed[0][0], $counter, $process) EndIf EndIf You can read from this, that the array $closed[0][0] is being read 3 times. And this goes on further in the code I did not show.
      My question boils down to this, should I make a 'temp' variable to hold that $closed[0][0] value until the function is done?
      It may not have a real impact on my small script, but I really am interested in the answer at least.
    • Nitrolord
      By Nitrolord
      I had this problem with PixelGetColor not giving me the same HEX Color as the AU3Info Tool and searched every were with no luck then had a OH DA moment LoL.
      The problem is that the
      "PixelGetColor ($mouseX[0], $mouseY[1])"
      is looking rite at the very tip of the mouse pointer not under it.  So you have to set a -3 after the [0] and [1].  
      "PixelGetColor ($mouseX[0] -3, $mouseY[1] -3)"
      to make it search next to the pointer not on the pointer.  You may have to adjust this a bit for your display but you should not have  to go more then -5.  -3 seems to work best for me.
      #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 141, 127, 276, 231) $Input1 = GUICtrlCreateInput("", 8, 8, 121, 21) $Label1 = GUICtrlCreateLabel("Press or Hold F1 to get Hex color at Mouse X -3, Y-3 Pos,", 8, 40, 124, 73) GUISetState(@SW_SHOW) HotKeySet("{f1}","MousePos") Func MousePos() $aPos = MouseGetPos() $PGC = PixelGetColor($aPos[0] -3, $aPos[1] -3) GUICtrlSetData($Input1, "0x" & Hex($PGC, 6)) EndFunc While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd