Merge pull request #3808 from radarhere/imagegrab

Added option to include layered windows in ImageGrab.grab on Windows
This commit is contained in:
Hugo 2019-05-04 16:00:43 +03:00 committed by GitHub
commit 82d9ea5eac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 6 deletions

View File

@ -9,8 +9,11 @@ try:
class TestImageGrab(PillowTestCase): class TestImageGrab(PillowTestCase):
def test_grab(self): def test_grab(self):
im = ImageGrab.grab() for im in [
self.assert_image(im, im.mode, im.size) ImageGrab.grab(),
ImageGrab.grab(include_layered_windows=True)
]:
self.assert_image(im, im.mode, im.size)
def test_grabclipboard(self): def test_grabclipboard(self):
if sys.platform == "darwin": if sys.platform == "darwin":

View File

@ -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) .. py:function:: PIL.ImageGrab.grab(bbox=None, include_layered_windows=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.
@ -20,6 +20,7 @@ or the clipboard to a PIL image memory.
.. versionadded:: 1.1.3 (Windows), 3.0.0 (macOS) .. versionadded:: 1.1.3 (Windows), 3.0.0 (macOS)
: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.
:return: An image :return: An image
.. py:function:: PIL.ImageGrab.grabclipboard() .. py:function:: PIL.ImageGrab.grabclipboard()

View File

@ -29,7 +29,7 @@ elif sys.platform == "darwin":
import subprocess import subprocess
def grab(bbox=None): def grab(bbox=None, include_layered_windows=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)
@ -38,7 +38,7 @@ def grab(bbox=None):
im.load() im.load()
os.unlink(filepath) os.unlink(filepath)
else: else:
size, data = grabber() size, data = grabber(include_layered_windows)
im = Image.frombytes( im = Image.frombytes(
"RGB", size, data, "RGB", size, data,
# RGB, 32-bit line padding, origin lower left corner # RGB, 32-bit line padding, origin lower left corner

View File

@ -323,11 +323,16 @@ PyObject*
PyImaging_GrabScreenWin32(PyObject* self, PyObject* args) PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
{ {
int width, height; int width, height;
int includeLayeredWindows = 0;
HBITMAP bitmap; HBITMAP bitmap;
BITMAPCOREHEADER core; BITMAPCOREHEADER core;
HDC screen, screen_copy; HDC screen, screen_copy;
DWORD rop;
PyObject* buffer; PyObject* buffer;
if (!PyArg_ParseTuple(args, "|i", &includeLayeredWindows))
return NULL;
/* step 1: create a memory DC large enough to hold the /* step 1: create a memory DC large enough to hold the
entire screen */ entire screen */
@ -346,7 +351,10 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
/* step 2: copy bits into memory DC bitmap */ /* step 2: copy bits into memory DC bitmap */
if (!BitBlt(screen_copy, 0, 0, width, height, screen, 0, 0, SRCCOPY)) rop = SRCCOPY;
if (includeLayeredWindows)
rop |= CAPTUREBLT;
if (!BitBlt(screen_copy, 0, 0, width, height, screen, 0, 0, rop))
goto error; goto error;
/* step 3: extract bits from bitmap */ /* step 3: extract bits from bitmap */