mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-13 05:06:49 +03:00
add option to capture all monitors on Windows
This commit is contained in:
parent
03452d138d
commit
fa6b80fddf
|
@ -8,7 +8,11 @@ try:
|
||||||
|
|
||||||
class TestImageGrab(PillowTestCase):
|
class TestImageGrab(PillowTestCase):
|
||||||
def test_grab(self):
|
def test_grab(self):
|
||||||
for im in [ImageGrab.grab(), ImageGrab.grab(include_layered_windows=True)]:
|
for im in [
|
||||||
|
ImageGrab.grab(),
|
||||||
|
ImageGrab.grab(include_layered_windows=True),
|
||||||
|
ImageGrab.grab(multimonitor=True),
|
||||||
|
]:
|
||||||
self.assert_image(im, im.mode, im.size)
|
self.assert_image(im, im.mode, im.size)
|
||||||
|
|
||||||
def test_grabclipboard(self):
|
def test_grabclipboard(self):
|
||||||
|
|
|
@ -11,7 +11,7 @@ or the clipboard to a PIL image memory.
|
||||||
|
|
||||||
.. versionadded:: 1.1.3
|
.. versionadded:: 1.1.3
|
||||||
|
|
||||||
.. py:function:: PIL.ImageGrab.grab(bbox=None, include_layered_windows=False)
|
.. py:function:: PIL.ImageGrab.grab(bbox=None, include_layered_windows=False, multimonitor=False)
|
||||||
|
|
||||||
Take a snapshot of the screen. The pixels inside the bounding box are
|
Take a snapshot of the screen. The pixels inside the bounding box are
|
||||||
returned as an "RGB" image on Windows or "RGBA" on macOS.
|
returned as an "RGB" image on Windows or "RGBA" on macOS.
|
||||||
|
@ -21,6 +21,7 @@ or the clipboard to a PIL image memory.
|
||||||
|
|
||||||
:param bbox: What region to copy. Default is the entire screen.
|
:param bbox: What region to copy. Default is the entire screen.
|
||||||
:param include_layered_windows: Includes layered windows. Windows OS only.
|
:param include_layered_windows: Includes layered windows. Windows OS only.
|
||||||
|
:param multimonitor: Capture all monitors. Windows OS only.
|
||||||
:return: An image
|
:return: An image
|
||||||
|
|
||||||
.. py:function:: PIL.ImageGrab.grabclipboard()
|
.. py:function:: PIL.ImageGrab.grabclipboard()
|
||||||
|
|
|
@ -29,7 +29,7 @@ else:
|
||||||
raise ImportError("ImageGrab is macOS and Windows only")
|
raise ImportError("ImageGrab is macOS and Windows only")
|
||||||
|
|
||||||
|
|
||||||
def grab(bbox=None, include_layered_windows=False):
|
def grab(bbox=None, include_layered_windows=False, multimonitor=False):
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
fh, filepath = tempfile.mkstemp(".png")
|
fh, filepath = tempfile.mkstemp(".png")
|
||||||
os.close(fh)
|
os.close(fh)
|
||||||
|
@ -37,8 +37,10 @@ def grab(bbox=None, include_layered_windows=False):
|
||||||
im = Image.open(filepath)
|
im = Image.open(filepath)
|
||||||
im.load()
|
im.load()
|
||||||
os.unlink(filepath)
|
os.unlink(filepath)
|
||||||
|
if bbox:
|
||||||
|
im = im.crop(bbox)
|
||||||
else:
|
else:
|
||||||
size, data = grabber(include_layered_windows)
|
offset, size, data = grabber(include_layered_windows, multimonitor)
|
||||||
im = Image.frombytes(
|
im = Image.frombytes(
|
||||||
"RGB",
|
"RGB",
|
||||||
size,
|
size,
|
||||||
|
@ -49,8 +51,10 @@ def grab(bbox=None, include_layered_windows=False):
|
||||||
(size[0] * 3 + 3) & -4,
|
(size[0] * 3 + 3) & -4,
|
||||||
-1,
|
-1,
|
||||||
)
|
)
|
||||||
if bbox:
|
if bbox:
|
||||||
im = im.crop(bbox)
|
x0, y0 = offset
|
||||||
|
left, top, right, bottom = bbox
|
||||||
|
im = im.crop((left - x0, top - y0, right - x0, bottom - y0))
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -322,15 +322,15 @@ PyImaging_DisplayModeWin32(PyObject* self, PyObject* args)
|
||||||
PyObject*
|
PyObject*
|
||||||
PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
int width, height;
|
int x = 0, y = 0, width, height;
|
||||||
int includeLayeredWindows = 0;
|
int includeLayeredWindows = 0, multimonitor = 0;
|
||||||
HBITMAP bitmap;
|
HBITMAP bitmap;
|
||||||
BITMAPCOREHEADER core;
|
BITMAPCOREHEADER core;
|
||||||
HDC screen, screen_copy;
|
HDC screen, screen_copy;
|
||||||
DWORD rop;
|
DWORD rop;
|
||||||
PyObject* buffer;
|
PyObject* buffer;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "|i", &includeLayeredWindows))
|
if (!PyArg_ParseTuple(args, "|ii", &includeLayeredWindows, &multimonitor))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* step 1: create a memory DC large enough to hold the
|
/* step 1: create a memory DC large enough to hold the
|
||||||
|
@ -339,8 +339,15 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
||||||
screen = CreateDC("DISPLAY", NULL, NULL, NULL);
|
screen = CreateDC("DISPLAY", NULL, NULL, NULL);
|
||||||
screen_copy = CreateCompatibleDC(screen);
|
screen_copy = CreateCompatibleDC(screen);
|
||||||
|
|
||||||
width = GetDeviceCaps(screen, HORZRES);
|
if (multimonitor) {
|
||||||
height = GetDeviceCaps(screen, VERTRES);
|
x = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||||
|
y = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||||
|
width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||||
|
height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||||
|
} else {
|
||||||
|
width = GetSystemMetrics(SM_CXSCREEN);
|
||||||
|
height = GetSystemMetrics(SM_CYSCREEN);
|
||||||
|
}
|
||||||
|
|
||||||
bitmap = CreateCompatibleBitmap(screen, width, height);
|
bitmap = CreateCompatibleBitmap(screen, width, height);
|
||||||
if (!bitmap)
|
if (!bitmap)
|
||||||
|
@ -354,7 +361,7 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
||||||
rop = SRCCOPY;
|
rop = SRCCOPY;
|
||||||
if (includeLayeredWindows)
|
if (includeLayeredWindows)
|
||||||
rop |= CAPTUREBLT;
|
rop |= CAPTUREBLT;
|
||||||
if (!BitBlt(screen_copy, 0, 0, width, height, screen, 0, 0, rop))
|
if (!BitBlt(screen_copy, 0, 0, width, height, screen, x, y, rop))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* step 3: extract bits from bitmap */
|
/* step 3: extract bits from bitmap */
|
||||||
|
@ -376,7 +383,7 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
|
||||||
DeleteDC(screen_copy);
|
DeleteDC(screen_copy);
|
||||||
DeleteDC(screen);
|
DeleteDC(screen);
|
||||||
|
|
||||||
return Py_BuildValue("(ii)N", width, height, buffer);
|
return Py_BuildValue("(ii)(ii)N", x, y, width, height, buffer);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
PyErr_SetString(PyExc_IOError, "screen grab failed");
|
PyErr_SetString(PyExc_IOError, "screen grab failed");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user