How to choose which screen ImageGrab.grab () captures in setting up multiple monitors?

As in the title, I wonder if there is a way to configure the ImageGrab.grab () module to capture, for example, the right screen, and not the left one in the setting with multiple monitors.

+6
source share
1 answer

Unfortunately, this is not possible because of how the PIL gets the dimensions of the display device. When it receives the device context, it receives one for all connected monitors:

screen = CreateDC("DISPLAY", NULL, NULL, NULL); 

( display.c , line 296, version 1.1.7)

However, to get the dimensions of the display, it uses this code:

 width = GetDeviceCaps(screen, HORZRES); height = GetDeviceCaps(screen, VERTRES); 

( display.c , lines 299-300, version 1.1.7)

Returns only the dimensions of the main, active monitor. All subsequent operations are performed with these widths and heights, resulting in a final image that is only the size of the main display.


To get a pop-up window of all connected monitors, these two lines must be replaced with something like:

 width = GetSystemMetrics(SM_CXVIRTUALSCREEN); height = GetSystemMetrics(SM_CYVIRTUALSCREEN); 

After that, you will need to recompile the PIL. This will give you the dimensions of the virtual screen, which is the "... bounding box of all display monitors." [ MSDN ]

A more correct implementation would be to use EnumDisplayMonitors to obtain device contexts for individual monitors, as well as change the ImageGrab.grab () interface (or add a new function) to allow the selection of a specific monitor whose device context will be used for other operations.

+6
source

Source: https://habr.com/ru/post/907893/


All Articles