AutoHotkey Community

It is currently May 27th, 2012, 8:36 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: April 17th, 2006, 12:48 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Show a Gui window with transparent background, but opaque controls. PixelGetColor returns the color of the pixel under the control (not the color of the control), which is not what we see on screen. It needs to be clarified in the help.
Code:
CoordMode Mouse, Screen

Gui Color,012345
Gui Add, Button, W60 H60
Gui Show, X200 Y0 W82 H80, xxx
Winset Transcolor, 012345, xxx

Loop
{
   MouseGetPos X, Y
   PixelGetColor Color, X, Y
   TrayTip,,<%Color%>
   Sleep 100
}


Is there an easy way to get the color of a visible pixel belonging to a partially transparent window?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 2:04 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
PixelGetColor is simply a wrapper for the OS's GetPixel() function. Here is the code behind it (converted to DllCall). Maybe you can tweak it do better things by giving it a different HDC (such as a window's).
Code:
hdc := DllCall("GetDC", "uint", 0)
if hdc
{
   ColorBGR := DllCall("GetPixel", "uint", hdc, "int", 100, "int", 10) ; Specify the pixel's screen coords.
   DllCall("ReleaseDC", "uint", 0, "uint", hdc)
   MsgBox %ColorBGR%
}

Concerning the docs, this would be a case of documenting something that isn't even documented at MSDN, so the behavior might vary from system to system (depending on video driver, for example). Maybe some kind of non-specific cautionary wording can be added. Suggestions are welcome.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 10:03 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Interesting.
Actually, I am not sure if that is tied to transparency.
If I put, for example, w300 and remove transparency, I get random results over the GUI area (outside the button), and even outside the GUI.
Code:
#Persistent
CoordMode Mouse, Screen

SetTimer ShowColor, 500

ShowColor:
   MouseGetPos x, y
   PixelGetColor color, x, y
   ToolTip %color%
Return

I have often 0xFFFFFF and sometime 0xFFFFFFFF (32bit value). Oh, the last value is CLR_INVALID (-1).
Over a SciTE window, I have CLR_INVALID everywhere...
I never tested this command before, but it seems quite unreliable... At least on my system (WinXP Home SP2, ATI Radeon 9250).

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 11:01 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
I searched how others pick colors on screen.
I found a CodeProject article explaining one technique: it uses GetPixel, indeed, but it creates a DC using hDC = CreateDC("DISPLAY",0,0,0);. Perhaps that's the main difference.
I tested the provided exe and it works quite well, including over SciTE...
Code:
#SingleInstance Force

#Persistent
CoordMode Mouse, Screen

offsetX = -40
offsetY = 0

hDC := DllCall("CreateDC", "Str", "DISPLAY", "UInt", 0, "UInt", 0, "UInt", 0)
If hDC = 0
{
   MsgBox 16, GetPixel, Cannot create DISPLAY's DC
   ExitApp
}

SetTimer ShowColor, 500

ShowColor:
   MouseGetPos x, y
   SetFormat Integer, D
   coords :=" (" . (x + offsetX) . ", " . (y + offsetY) . ")"
   SetFormat Integer, Hex
   PixelGetColor color, x + offsetX, y + offsetY, RGB
   If (color = 0xFFFFFFFF)
      color = Invalid!
   colorBGR := DllCall("GetPixel", "UInt", hDC, "Int", x + offsetX, "Int", y + offsetY)
   If (colorBGR = 0xFFFFFFFF)
   {
      ToolTip %coords% Invalid! / %color%
   }
   Else
   {
      colorBGR += 0x1000000
      StringUpper colorBGR, colorBGR
;~       StringTrimLeft colorBGR, colorBGR, 3
;~       ToolTip %colorBGR%
       StringMid b, colorBGR, 4, 2
       StringMid g, colorBGR, 6, 2
       StringMid r, colorBGR, 8, 2
       ToolTip %coords% %r% %g% %b% / %color%
   }
Return

Escape::
DllCall("DeleteDC", "UInt", hDC)
ExitApp

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Last edited by PhiLho on April 18th, 2006, 12:43 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 11:40 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
It could be that the cursor is blocking the mouse somehow. You might try using PixelGetColor on a pixel that is definitely not under the mouse cursor.

If PixelGetColor is unreliable as you suggest, that would be a pretty big surprise because it has been a command since the beta versions of AHK in December 2003, yet there have been no complaints about its reliability (except in certain games, where a few have said it always gets a black pixel).

By contrast, there have been complaints about the performance of PixelGetColor. So I'd be hesitant to change it to a potentially slower method, especially if there's a chance it would break existing scripts by extracting different colors from games and other apps.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 6:46 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
PhiLho's script works more reliably than PixelgetColor in normal windows, but on the button in my partially transparent Gui window, it fails, too.
Chris wrote:
It could be that the cursor is blocking the mouse somehow. You might try using PixelGetColor on a pixel that is definitely not under the mouse cursor.
It is not the cursor. Even if I get the pixel color from x-60, y-60 of the cursor coordinates, it is the same, getting the pixel colors underneath, not the visible one.
Chris wrote:
If PixelGetColor is unreliable as you suggest, that would be a pretty big surprise because it has been a command since the beta versions of AHK in December 2003, yet there have been no complaints about its reliability...
Why don't you just try the script I posted to demonstrate the problem. If you think, getting the color of a covered pixel (instead of the visible one) is the right behavior, it has to be documented, because most of us would expect otherwise.

I tried the script on different computers (all XP SP2). They behave identically, so it is unlikely a video driver problem.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 7:20 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
I forgot to test again your GUI problem...
Well, it acts like all the GUI is transparent, including the title bar... Perhaps Windows see the whole window as transparent (for GetPixel at least), even if it displays some parts as opaque. Strange...

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2006, 9:52 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Laszlo, I should clarify that my previous post was in response to PhiLho's two posts, not yours. Sorry if it caused any misunderstanding.

Laszlo wrote:
Why don't you just try the script I posted to demonstrate the problem.
I never doubted that what you said was true; sorry if I gave you another impression.

Quote:
If you think, getting the color of a covered pixel (instead of the visible one) is the right behavior, it has to be documented, because most of us would expect otherwise.
All I said was that I don't know what the correct behavior is because MSDN doesn't document it. :)

Quote:
I tried the script on different computers (all XP SP2). They behave identically, so it is unlikely a video driver problem.
Thanks. I'll document this as a known limitation.

If anyone else has noticed unreliability with PixelGetColor in normal windows (not games or transparent windows), please let me know.

Thanks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 18th, 2006, 11:25 am 
Offline

Joined: November 15th, 2005, 11:15 am
Posts: 537
Location: Germany
Hi PhiLho,
i've tried your script:

black -> 0 0 0
red ->00 00 ff
cyan ->00 ff ff
blue -> 00 00 ff
green ->00 00 80

Red and blue have the same values. When changing the tooltip to show
Code:
   ToolTip, %colorBGR%

it shows the correct values 0xff and 0x0000ff

Just what I have noticed

Ciao
Micha


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 18th, 2006, 12:43 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Micha, you were right, there was a strange bug I didn't care to fully understand. Anyway, I wanted to use a trick given by Laszlo, giving a simplier code, giving correct results.
I updated the code above. Thanks for pointing that out.
Mmm, I even updated the code to show in parallel the results of the DllCall and those of PixelGetColor.

Chris wrote:
If anyone else has noticed unreliability with PixelGetColor in normal windows (not games or transparent windows), please let me know.

I already pointed out a problem with SciTE, where all results are "CLR_INVALID" or 0xFFFFFF.
With my new version, I tested in Win98SE, with an offset to be sure of no interference with the cursor (although you mention it should make no difference outside games).
The results are very strange...
For example, over the AutoHotkey Help window, the results are consistent when the window is active, but when it becomes inactive, PixelGetColor (PGC) gives seemingly random results, mostly 0xFFFFFF.
Starting Wordpad, over the title bar, the result of PGC varies depending where the bar is...
Sometime, both results are stuck on 0xFFFFFF, then restart of behave correctly.

I can't test on WinXP right now, but I will update this post when I will get the opportunity.

Please, try and test my little snippet, to see if there is a problem only on my systems/applications/themes/color schemes/whatever.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 6th, 2010, 2:42 am 
Offline

Joined: January 6th, 2010, 2:37 am
Posts: 1
....俺一点也没看懂


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 6th, 2010, 11:55 pm 
Offline

Joined: October 9th, 2006, 8:19 pm
Posts: 236
Location: Finland
Since this old thread has been bumbed, I'd like to tell my opinion about the reliability of PixelGetColor:
It seems that no one of those famous posters didn't notice a simple thing although...
PhiLho wrote:
For example, over the AutoHotkey Help window, the results are consistent when the window is active, but when it becomes inactive, PixelGetColor (PGC) gives seemingly random results, mostly 0xFFFFFF.

For if you specify
Code:
CoordMode Mouse, Screen
, you should also specify
Code:
CoordMode Pixel, Screen
.
I found this months ago, but didn't want to bump it (to be not regarded as a "besserwisser") :roll:

_________________
Pekka Vartto


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group