我正在开发一个小型自动化工具,它可以拍摄屏幕快照,进行一些模板匹配,然后做出相应的响应。我以前为此使用过 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 从磁盘重新加载,然后获取像素数据,但是这样做的 IO 开销太大而无法使用。
现在,我在国外使用 Windows API,但是,通过阅读 MSDN,我发现了这一点:
内存设备上下文
它是内存中的一个位数组,应用程序可以临时使用它来存储在正常绘图表面上创建的位图的颜色数据。因为位图与设备兼容,所以内存 DC 有时也称为兼容设备上下文。
所以,看起来这些 DC 确实存储了像素数据,但我只是不知道如何访问它。我如何获得该底层像素阵列?