如何在多显示器设置中选择 ImageGrab.grab() 抓取哪个屏幕?
就像标题所说的,我很好奇有没有办法设置ImageGrab.grab()这个模块,让它在多屏幕的情况下抓取右边的屏幕,而不是左边的屏幕。
1 个回答
9
很遗憾,由于PIL获取显示设备尺寸的方式,这个操作是不可行的。当它获取设备上下文时,确实会获取到所有连接的显示器:
screen = CreateDC("DISPLAY", NULL, NULL, NULL);
(display.c,第296行,版本1.1.7)
但是,要获取显示尺寸,它使用了以下代码:
width = GetDeviceCaps(screen, HORZRES);
height = GetDeviceCaps(screen, VERTRES);
(display.c,第299-300行,版本1.1.7)
这段代码只返回主显示器的尺寸。之后的所有操作都是基于这个宽度和高度值进行的,最终得到的图像大小仅仅是主显示器的大小。
如果想要获取所有连接显示器的屏幕截图,就需要把那两行代码替换成类似下面的内容:
width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
然后你需要重新编译PIL。这样就能得到虚拟屏幕的尺寸,也就是“...所有显示器的边界矩形。” [MSDN]
更正确的做法是使用EnumDisplayMonitors来获取每个显示器的设备上下文,同时修改ImageGrab.grab()的接口(或者添加一个新功能),以便选择特定的显示器,这样就可以使用该显示器的设备上下文进行后续操作。