Python PIL库 - 有没有办法选择在多监视器设置中的ImageGrab.grab()抓取哪个屏幕?
问题描述:
就像标题所说,我很好奇,如果有一种方法来配置ImageGrab.grab()模块来抓取,例如,右屏幕,而不是多显示器设置中的左侧。Python PIL库 - 有没有办法选择在多监视器设置中的ImageGrab.grab()抓取哪个屏幕?
答
不幸的是,由于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)
其中只返回主动监视器的尺寸。所有后续操作都使用这些宽度和高度值完成,导致最终图像仅为主显示屏的大小。
为了接收所有连接的显示器的screengrab,这两条线将需要的东西,如更换:
width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
之后,你需要重新编译PIL。这将为您提供虚拟屏幕的尺寸,即“......所有显示器的边界矩形”。 [MSDN]
更正确的实现方法是使用EnumDisplayMonitors来获取各个监视器的设备上下文,以及更改ImageGrab.grab()的接口(或添加新函数)以允许选择特定监视器的设备上下文将用于其余操作。
在你的第二个实现中,我能够通过enumDisplayMonitors找到监视器的句柄..但是对于下一步,我需要C还是可以在ImageGrab模块中完成?如果我正确地关注你,我必须创建的函数需要修改CreateDC(“DISPLAY”,NULL,NULL)调用,用'DISPLAY'代替我想要拍摄快照的设备句柄? – Zack 2012-02-08 02:43:33
对不起,我不清楚,这两个选项都需要修改PIL的C源代码并重新编译它。你是对的,CreateDC函数是需要改变的。 – Andrew 2012-02-08 02:55:47