Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
5 changes: 3 additions & 2 deletions docs/reference/ImageGrab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ 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, it uses windowid.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's windowid? There's no other mention in the docs or code.

Copy link
Member

@radarhere radarhere Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed a commit to describe it as a CGWindowID instead.


.. 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