python - 如何在 python 中将 COLORREF 从 GetPixel() 转换为 RGB?

标签 python winapi ctypes

我正在使用 ctypes 编写一个程序,它会返回我在屏幕上单击鼠标的任何位置的 RGB 像素。我正在使用 GetPixel()返回 COLORREF ,我认为这是一个 ABGR 十六进制颜色空间(即#00BBGGRR)。问题是我不确定如何将 COLORREF 转换为 RGB。

这是一个代码片段:

from ctypes import *
from ctypes.wintypes import LONG
from sys import exit

# DLLs
user32 = windll.user32
gdi32 = windll.gdi32

# Virtual Keys
LM_BUTTON = 0x01
RM_BUTTON = 0x02


def main():
    while True:
        if get_key_state(LM_BUTTON) > 1:  # Detect key press.
            colorref = get_pixel(*get_cursor())
            print(colorref)
            while get_key_state(LM_BUTTON) > 1:   # Wait for key release.
                pass
        if get_key_state(RM_BUTTON) > 1:
            exit()


class POINT(Structure):
    _fields_ = [('x', LONG), ('y', LONG)]


def get_cursor():
    pos = POINT()
    user32.GetCursorPos(byref(pos))
    return pos.x, pos.y


def get_pixel(x, y, hdc=0):
    dc = user32.GetDC(hdc)
    colorref = gdi32.GetPixel(dc, x, y)
    return colorref


def get_key_state(vkey):
    return user32.GetKeyState(vkey)


if __name__ == '__main__':
    main()

有一些宏,比如RGB macro , 将 COLORREF 转换为 RGB,但我不确定如何使用 ctypes 调用这些宏。

我已经尝试创建一个转换函数,但是它hacky 并且非常丑陋,而且我觉得我正在采取不必要的步骤来实现它。在 python 中必须有更常规的方法来执行此操作吗?

def get_rgb(colorref):
    color_hex = hex(colorref)[2:].zfill(6)[::-1]
    rgb = tuple(int(rgb, 16) if '0' not in (rgb:=color_hex[i:i+2]) else int(rgb[::-1], 16) for i in (0, 2, 4))
    return rgb

最佳答案

COLORREF 被定义为 32 位值(来自 windef.h):

typedef DWORD   COLORREF;

还有那 3 个宏(来自 wingdi.h):

#define RGB(r,g,b)          ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))

#define GetRValue(rgb)      (LOBYTE(rgb))
#define GetGValue(rgb)      (LOBYTE(((WORD)(rgb)) >> 8))
#define GetBValue(rgb)      (LOBYTE((rgb)>>16))

因此,通过查看这些宏,我们可以看到:

  • R 组件是低位字节(位 0-7)
  • G 组件从第 8 位到第 15 位。
  • B 组件来自位 16 - 23。

所以基本上你所要做的就是屏蔽和位移:

def rgba(colorref):
    mask = 0xff
    return [(colorref & (mask << (i * 8))) >> (i * 8) for i in range(4)]

测试:

>>> r, g, b, a = rgba(0x01020304)
>>> print(r,g,b,a)
4 3 2 1

关于python - 如何在 python 中将 COLORREF 从 GetPixel() 转换为 RGB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58639656/

相关文章:

linux - Chefspec 在 Linux 上删除 Win32::Service

python - 扩展 ctypes 以指定字段重载

python - 未关闭的标签 'block' 。寻找 : endblock 之一

python - 全局变量赋值问题

python - python中函数参数列表中的*代表什么?

windows - XP 系统上的 GetProductInfo

python - Beautiful Soup 4 .string() 'NoneType' 对象不可调用

c - C 和 D 中相同的_exact_代码会给出不同的结果——为什么?

python - Python可以调用DLL中的Delphi函数吗?

python - 将 C 结构传递给 C DLL 中的函数