如何在Windows设备上下文中访问像素数组?

0 投票
1 回答
987 浏览
提问于 2025-04-17 18:51

我正在开发一个小工具,它可以截取屏幕快照,进行一些模板匹配,然后做出相应的反应。之前我用过PIL这个库,但它的ImageGrab功能只能抓取主显示器的内容,我需要能够抓取连接到电脑的任何显示设备。经过简单的搜索,我找到了以下代码作为解决方案。

截图代码

def capture_display():
    monitors = win32api.EnumDisplayMonitors(None, None)
    hwnd = monitors[1][1].handle
    l,t,r,b = monitors[1][2]
    w = r - l
    h = b

    hwndDC = win32gui.GetWindowDC(hwnd)
    mfcDC  = win32ui.CreateDCFromHandle(hwndDC)
    saveDC = mfcDC.CreateCompatibleDC()

    saveBitMap = win32ui.CreateBitmap()
    saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
    saveDC.SelectObject(saveBitMap)
    saveDC.BitBlt((0, 0), (w, h),  mfcDC,  (l, t),  win32con.SRCCOPY)
    saveBitMap.SaveBitmapFile(saveDC,  'screencapture.bmp')

这个方法效果很好。不过,它会把图像保存下来。我其实只需要访问内存中的像素数组。

当然,我可以选择先保存图像,然后通过PIL从磁盘重新加载,再获取像素数据,但这样做的输入输出开销太大,没什么用。

现在,我对Windows API还不太熟悉,不过在MSDN上阅读时,我发现了以下内容:

内存设备上下文

它是内存中的一个位数组,应用程序可以暂时使用它来存储在普通绘图表面上创建的位图的颜色数据。因为位图与设备兼容,所以内存DC有时也被称为兼容设备上下文。

所以,看起来这些DC确实存储了像素数据,但我完全不知道怎么访问它。我该如何获取这个底层的像素数组呢?

1 个回答

2

最简单的方法是使用 GetDIBits 函数(在Python中,可以用 ctypes.windll.gdi32.GetDIBits 来调用):http://msdn.microsoft.com/en-us/library/windows/desktop/dd144879(v=vs.85).aspx

撰写回答