Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install Pillow and pyscreenshot, call pyscreenshot.grab(), then save the returned Pillow image. Use grab(bbox=(left, top, right, bottom)) for a rectangle. The API is small, but capture also depends on an operating-system backend and your desktop session. The project’s current README says pyscreenshot is obsolete for most uses because Pillow’s ImageGrab now works on Windows, macOS, and Linux; pyscreenshot remains useful when you need backend selection, certain Wayland routes, subprocess isolation, or a backend that behaves better on a particular machine.

Install pyscreenshot and its image dependency

Create or activate the Python environment that will run the capture, then install both packages:

python3 -m pip install Pillow pyscreenshot

The README lists Python 3.9, 3.10, and 3.11 as supported versions. PyPI currently shows pyscreenshot 3.1 (the release file was uploaded on March 12, 2023); its metadata also advertises a broad Python >=3.4 requirement, which is not the same as the narrower, currently listed tested versions. Check the package metadata for your interpreter before deploying.

Installing the wrapper does not install every possible capture engine. pyscreenshot can use Pillow, MSS, desktop D-Bus services, or command-line programs such as scrot, maim, ImageMagick, Grim, and platform screenshot tools. A missing or unusable backend is the most common reason that installation succeeds but capture fails.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture the entire screen

The documented interface aliases pyscreenshot to ImageGrab, making the call resemble Pillow’s API:

import pyscreenshot as ImageGrab

im = ImageGrab.grab()
im.save("screenshot.png")

grab() returns an image object held in Pillow memory. The save() method chooses the output format from the filename extension in common cases, so .png, .jpg, and .webp are convenient choices. Questions about image conversion, color modes, and Pillow file handling belong to Pillow’s documentation.

Use an absolute output path when running from a scheduler or service, and make sure the process has permission to create the destination directory. The capture is non-interactive: the project says the mouse pointer is not visible.

Capture a selected rectangle

Pass a four-number bounding box in the form (left, top, right, bottom):

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import pyscreenshot as ImageGrab

im = ImageGrab.grab(bbox=(10, 10, 510, 510))
im.save("region.png")

The first pair is the upper-left corner and the second pair is the lower-right corner, in desktop coordinates. For a 500-pixel-wide region beginning at x 10, use right = 510. Coordinates are supplied by the operating system; multi-monitor arrangements can therefore include negative values or a virtual desktop whose origin is not the primary display’s upper-left corner.

Validate coordinates before calling the API when they come from user input. A practical helper keeps the rectangle ordered and rejects an empty area:

import pyscreenshot as ImageGrab

def capture_box(box, filename):
    left, top, right, bottom = box
    if right <= left or bottom <= top:
        raise ValueError("right and bottom must be greater than left and top")
    image = ImageGrab.grab(bbox=(left, top, right, bottom))
    image.save(filename)

capture_box((10, 10, 510, 510), "region.png")

Choose a backend deliberately

When the default route does not work, force a backend that is installed and appropriate for the current desktop:

import pyscreenshot as ImageGrab

image = ImageGrab.grab(backend="scrot")
image.save("scrot-shot.png")

The backend name is not an automatic installer. For example, selecting scrot requires the scrot executable to be present and discoverable in PATH. The README lists integrations for Pillow, MSS, xdg-desktop-portal Screenshot, GNOME Shell Screenshot, scrot, maim, ImageMagick, PyQt5, PySide2, wxPython, Grim, Quartz, and macOS screencapture. Availability and behavior vary by operating system, desktop, and session type.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

pyscreenshot also documents an MSS route with subprocess execution disabled:

import pyscreenshot as ImageGrab

image = ImageGrab.grab(backend="mss", childprocess=False)
image.save("mss-shot.png")

The project describes subprocess mode as safer isolation. Turning it off can improve speed in some environments, but it removes that isolation and may expose the main process to backend problems. Treat this as a measured optimization, not a default setting.

Wayland, X11, and desktop-session behavior

Wayland capture is compositor- and portal-dependent. The project documents three routes:

  • xdg-desktop-portal: D-Bus org.freedesktop.portal.Screenshot on desktops that provide the portal.
  • GNOME: D-Bus org.gnome.Shell.Screenshot.
  • wlroots compositors: Grim through wlr-screencopy-unstable-v1; the README specifically says this works with Sway, not GNOME or KDE.

If both Wayland and X are available, the project prefers Wayland because Xwayland cannot be used for screenshot capture. Portal security can display a confirmation dialog, so an unattended job may stop waiting for user approval. KDE Wayland may show a notification, and GNOME may show a screenshot flash. These effects are desktop behavior, not image content that pyscreenshot can universally suppress.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Interactive selection is not supported by the project’s general interface. If you need a user to drag a rectangle, obtain the coordinates with a separate desktop tool or GUI and then pass them as bbox.

pyscreenshot or Pillow ImageGrab?

The maintainers’ current guidance begins with “TL;DR: Use Pillow.” Pillow’s ImageGrab now supports Linux and macOS as well as Windows, so it is normally the simpler direct dependency. pyscreenshot is worth keeping when one of its backend choices solves a concrete problem.

Decision point Prefer Pillow ImageGrab when… Prefer pyscreenshot when…
API simplicity You want the shortest dependency chain and direct Pillow interface. You want one wrapper API while trying different capture engines.
Wayland Your Pillow route works in the target compositor. You need the documented portal, GNOME Shell, or Grim route.
Backend choice The built-in route is reliable on every deployment. You must select MSS, scrot, maim, ImageMagick, or another listed integration.
Process isolation A single in-process call is acceptable. You value optional subprocess isolation or need to compare isolated and in-process routes.
Speed Your measured capture time is already adequate. A benchmark on your own machine shows a backend setting is faster.

There is no universal speed winner. The README’s sample timings were measured on Ubuntu 22.04 X11 with pyscreenshot 3.1, Pillow 9.0.1, MSS 7.0.1, and specific subprocess settings; they are not a current cross-platform benchmark. Measure the backend and settings you will actually deploy.

Make captures repeatable in a script

A small command-line program makes paths, regions, and backend choices explicit:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#!/usr/bin/env python3
import argparse
from pathlib import Path
import pyscreenshot as ImageGrab

parser = argparse.ArgumentParser()
parser.add_argument("output", type=Path)
parser.add_argument("--bbox", nargs=4, type=int, metavar=("LEFT", "TOP", "RIGHT", "BOTTOM"))
parser.add_argument("--backend")
args = parser.parse_args()

kwargs = {}
if args.bbox:
    left, top, right, bottom = args.bbox
    if right <= left or bottom <= top:
        parser.error("RIGHT must exceed LEFT and BOTTOM must exceed TOP")
    kwargs["bbox"] = (left, top, right, bottom)
if args.backend:
    kwargs["backend"] = args.backend

image = ImageGrab.grab(**kwargs)
args.output.parent.mkdir(parents=True, exist_ok=True)
image.save(args.output)
print(f"saved {args.output}")

Examples:

python capture.py full.png
python capture.py panel.png --bbox 0 0 900 700
python capture.py shot.png --backend scrot

For a service, log the selected backend, session type (X11 or Wayland), output path, and exception text. Do not silently retry indefinitely: a portal prompt or unavailable display usually requires an environment fix rather than more retries.

Troubleshooting common failures

“No backend” or executable-not-found errors

Install the operating-system utility named by the backend, or remove the forced backend= argument and test the default. Confirm the executable is on the same user’s PATH as the Python process. In containers and minimal servers, no graphical capture service may exist at all.

Works in a terminal but fails from cron, SSH, or systemd

Those contexts often lack DISPLAY, Wayland session variables, D-Bus access, or permission to connect to the desktop. Run the job inside the logged-in graphical session, pass only the required environment deliberately, and verify that the target user owns the display connection. A headless server cannot capture a physical desktop that is not running.

Wayland shows a dialog or hangs

The portal may require confirmation. Use a compositor-supported non-interactive route such as the documented Grim path where applicable, or run the capture where a user can approve the request. Grim is documented for Sway, not GNOME or KDE.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The image is black, partial, or from the wrong monitor

Check the session type, monitor geometry, and coordinates. Try another available backend, and test a full-screen capture before a bbox. Negative coordinates can be valid on a multi-monitor virtual desktop.

Capture is too slow

Benchmark the default and a backend such as MSS on the actual machine. The project suggests testing available settings; disabling child processes may improve speed but trades away isolation. Avoid presenting a README timing as a guarantee.

The output file is missing or has the wrong format

Use an absolute writable path and a recognized extension. Ensure the process reaches save(); print or log the destination after saving. Pillow performs the image encoding, so format-specific errors originate there rather than in coordinate capture.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your real goal is a webpage image rather than the physical desktop, ScreenshotNeo provides a website screenshot API. One GET request returns PNG, JPEG, WebP, or PDF; it is not dependent on your local X11 or Wayland session.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for parameters and response headers. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status with X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.

FAQ

Does pyscreenshot capture the mouse cursor?

The project says its interactive capture is not supported and the mouse pointer is not visible. A custom backend can have its own behavior, so verify it separately if the pointer matters.

Can I use pyscreenshot without Pillow?

The documented installation includes Pillow, and the returned image uses Pillow’s memory and saving APIs. Install both packages for the supported examples.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Is pyscreenshot actively current?

PyPI displays version 3.1, released in 2023, while the project README calls the package obsolete for most cases. Recheck package metadata and backend support before selecting it for a new long-lived application.

Frequently Asked Questions

Can pyscreenshot record a video or a sequence of frames?

It is a still-image capture interface. For video, use a screen-recording tool or repeatedly call a capture method with timing and encoding handled by a separate library.

Will a screenshot taken through a remote desktop look identical to the local display?

Not necessarily. Remote sessions can expose a different virtual monitor, scaling factor, compositor, or permission boundary. Test in the exact session used in production.

How do I capture a webpage after it finishes loading?

pyscreenshot captures the desktop, not a URL. Use a browser automation workflow or a web screenshot API such as ScreenshotNeo when the input is a webpage.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.