Python中ctypes调用gdi32.GetPixel()返回值不准确问题
解决GetPixel获取屏幕像素颜色不一致的问题
问题根源
你的代码存在两个关键问题:
- DC获取时机错误:先调用
GetDC(0)获取屏幕DC,再设置DPI感知。设置DPI感知会改变进程的缩放行为,导致之前获取的DC与当前进程的DPI上下文不匹配,读取的坐标无法正确映射到物理像素,每次实际读取的是不同的像素点,颜色自然出现差异。 - COLORREF解析方式不可靠:用
int.to_bytes解析GetPixel返回的COLORREF值,不符合Windows API对该返回值的定义标准。
修正后的代码
import time import ctypes # 先设置DPI感知,再获取屏幕DC ctypes.windll.shcore.SetProcessDpiAwareness(2) DC = ctypes.windll.user32.GetDC(0) def getpixel(x, y): color_ref = ctypes.windll.gdi32.GetPixel(DC, x, y) # COLORREF格式为0x00BBGGRR,通过位运算拆分RGB分量 r = color_ref & 0xFF g = (color_ref >> 8) & 0xFF b = (color_ref >> 16) & 0xFF return (r, g, b) try: while True: time.sleep(1) print(getpixel(0, 0)) finally: # 程序结束时释放DC,避免系统资源泄漏 ctypes.windll.user32.ReleaseDC(0, DC)
修正说明
- 调整执行顺序:先设置DPI感知,再获取屏幕DC,确保DC的DPI上下文与进程一致,坐标能正确映射到物理屏幕像素。
- 标准解析COLORREF:通过位运算直接提取R、G、B分量,完全符合Windows API对
GetPixel返回值的定义,结果更准确。 - 添加资源释放:在程序结束时调用
ReleaseDC释放屏幕DC,避免系统资源长期占用。
内容的提问来源于stack exchange,提问作者sandwichwasher
相关产品推荐
相关产品推荐

