Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/reference/ImageGrab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ or the clipboard to a PIL image memory.
.. versionadded:: 7.1.0

:param window:
HWND, to capture a single window. Windows only.
Capture a single window. On Windows, this is a HWND. On macOS, this is a
CGWindowID.

.. versionadded:: 11.2.1
.. versionadded:: 11.2.1 Windows support
.. versionadded:: 12.0.0 macOS support
:return: An image

.. py:function:: grabclipboard()
Expand Down
36 changes: 32 additions & 4 deletions src/PIL/ImageGrab.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,45 @@ def grab(
fh, filepath = tempfile.mkstemp(".png")
os.close(fh)
args = ["screencapture"]
if bbox:
if window:
args += ["-l", str(window)]
elif bbox:
left, top, right, bottom = bbox
args += ["-R", f"{left},{top},{right-left},{bottom-top}"]
subprocess.call(args + ["-x", filepath])
im = Image.open(filepath)
im.load()
os.unlink(filepath)
if bbox:
im_resized = im.resize((right - left, bottom - top))
im.close()
return im_resized
if window:
# Determine if the window was in retina mode or not
# by capturing it without the shadow,
# and checking how different the width is
fh, filepath = tempfile.mkstemp(".png")
os.close(fh)
subprocess.call(
["screencapture", "-l", str(window), "-o", "-x", filepath]
)
with Image.open(filepath) as im_no_shadow:
retina = im.width - im_no_shadow.width > 100
os.unlink(filepath)

# Since screencapture's -R does not work with -l,
# crop the image manually
if retina:
left, top, right, bottom = bbox
im_cropped = im.resize(
(right - left, bottom - top),
box=tuple(coord * 2 for coord in bbox),
)
else:
im_cropped = im.crop(bbox)
im.close()
return im_cropped
else:
im_resized = im.resize((right - left, bottom - top))
im.close()
return im_resized
return im
elif sys.platform == "win32":
if window is not None:
Expand Down
Loading