Reputation: 13
I am trying to grab the color of a pixel on screen. GetPixel() is giving me something close to the actual color, but different every time.
I've tried setting the dpi awareness but that has not solved the issue.
This is my current code:
import time
import ctypes
DC = ctypes.windll.user32.GetDC(0)
ctypes.windll.shcore.SetProcessDpiAwareness(2)
def getpixel(x, y):
return tuple(int.to_bytes(ctypes.windll.gdi32.GetPixel(DC,x,y), 3, "little"))
while True:
time.sleep(1)
print(getpixel(0, 0))
This is what it outputs:
(116, 106, 99)
(100, 91, 85)
(113, 104, 98)
(114, 105, 99)
(100, 92, 87)
(114, 105, 100)
(113, 103, 96)
(100, 92, 87)
(110, 100, 94)
Upvotes: 0
Views: 413
Reputation: 178179
The OP code worked for me as is, but it does have the risk that the HDC returned could be truncated if it doesn't fit in 32 bits (the default return value if .restype
is not defined for the function.
Here's a fully-specified example that should work properly on a 32- or 64-bit Windows OS. It's overkill, but guarantees all the types are converted correctly between C and Python. It's extended to read the color at the cursor position:
import time
import ctypes as ct
import ctypes.wintypes as w
HRESULT = w.LONG
class COLORREF(ct.Structure):
_fields_ = (('r', ct.c_ubyte),
('g', ct.c_ubyte),
('b', ct.c_ubyte),
('unused', ct.c_ubyte))
def __repr__(self):
return f'COLORREF(r={self.r}, g={self.g}, b={self.b})'
user32 = ct.WinDLL('user32')
GetDC = user32.GetDC
GetDC.argtypes = w.HWND,
GetDC.restype = w.HDC
GetCursorPos = user32.GetCursorPos
GetCursorPos.argtypes = w.PPOINT,
GetCursorPos.restype = w.BOOL
shcore = ct.WinDLL('shcore')
SetProcessDpiAwareness = shcore.SetProcessDpiAwareness
SetProcessDpiAwareness.argtypes = ct.c_int,
SetProcessDpiAwareness.restype = HRESULT
gdi32 = ct.WinDLL('gdi32')
GetPixel = gdi32.GetPixel
GetPixel.argtypes = w.HDC, ct.c_int, ct.c_int
GetPixel.restype = COLORREF
hdc = GetDC(None)
SetProcessDpiAwareness(2)
p = w.POINT()
while True:
time.sleep(.1)
GetCursorPos(ct.byref(p))
print(f'({p.x}, {p.y}) -> {GetPixel(hdc, p.x, p.y)}')
Upvotes: 0