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.

For a Python script running unattended on a computer with an accessible graphical desktop, PyAutoGUI can capture the screen and save it in one call: pyautogui.screenshot("screenshot.png"). The important qualification is that “background” describes how the script runs, not whether a display exists: a service without access to a desktop cannot be assumed to capture desktop pixels. Capturing an application window hidden behind other windows is also a different task from capturing the whole screen.

Save a screenshot from a Python script

Install PyAutoGUI and its platform prerequisites for your operating system, then pass a filename to screenshot(). The call saves the image and returns a Pillow image object, so you can also inspect or process it in Python. See the PyAutoGUI screenshot documentation for current installation requirements.

import pyautogui

image = pyautogui.screenshot("screenshot.png")
print(f"Saved screenshot: {image.size}")

To save only part of the display, use region=(left, top, width, height). Coordinates are measured from the display’s top-left; width and height describe the captured rectangle.

import pyautogui

image = pyautogui.screenshot(
    "screenshot.png",
    region=(0, 0, 800, 600),
)

PyAutoGUI’s documentation lists Pillow as a screenshot requirement and scrot as a Linux dependency; on macOS it uses the system screencapture command. Check the instructions for your current OS and distribution rather than assuming a package installation is identical everywhere.

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

Make “background” work: the display and file must be available

A scheduled task, daemon, or worker runs under a particular user account and environment. A successful run from your terminal does not prove that the same script can see the same graphical display when launched unattended. Test it as the service or scheduled-task account, in the session and environment where it will run.

  • Confirm display access. On Linux, inspect DISPLAY and verify that the process can access the indicated display. MSS uses DISPLAY by default and permits an explicit display value such as :0.0. A headless host with no accessible desktop should not be assumed to have desktop pixels available. See the MSS usage documentation.
  • Use an absolute output path. A service’s working directory may differ from the directory used in an interactive shell. Create the destination directory in advance and grant the running account write permission.
  • Choose a naming policy. Reusing screenshot.png overwrites that path if the capture library or your code writes it again. Use a timestamp or another unique name when you need to retain multiple captures.
  • Check the target geometry. Verify region coordinates and bounds on the actual display. PyAutoGUI uses left, top, width, and height; other libraries expose their own bounding-box or monitor forms.
  • Protect the output. Screenshots can contain account details, messages, or other sensitive material. Restrict access to the destination and set a retention policy appropriate to what is visible.

These are deployment checks, not guarantees that a capture library can create a desktop session. The capture APIs document ways to read an available display; they do not make an inaccessible or nonexistent desktop available to a background process.

Choose a library for monitor, region, or window capture

For a single full-screen shot or a simple rectangle, PyAutoGUI is a direct starting point. For repeated captures, explicit monitor selection, or access to pixel data, MSS offers monitor and region capture and can save PNG output or convert the result to a Pillow image. If your workflow is already Pillow-centered, ImageGrab provides screen capture and some platform-specific options. These interfaces rely on system capture facilities, so choose based on the target, operating system, dependencies, and processing needs—not on an assumed universal speed ranking.

Need Starting point Check before deployment
One full-screen image or rectangle PyAutoGUI Pillow and OS capture prerequisites; region coordinates.
Repeated captures, a specific monitor or region, or pixel processing MSS Display/backend access, monitor choice, and output conversion.
Pillow-based image workflow, Windows multi-screen capture, or supported single-window capture ImageGrab Installed Pillow version and the exact operating-system/API support.

Use MSS for repeated captures or monitor selection

MSS documents a monitor API, region capture, and PNG-saving examples. Convert a captured monitor directly to a Pillow image and save it as follows:

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.
from mss import MSS

with MSS() as sct:
    image = sct.grab(sct.primary_monitor).to_pil()
    image.save("screenshot.png")

For repeated captures, MSS recommends reusing an MSS instance rather than opening one for every capture. On Linux it reads DISPLAY by default; you can supply an explicit display, for example MSS(display=":0.0"). If you need another monitor, consult the MSS usage guide and its examples for monitor selection, region capture, and PNG output through mss.tools.to_png(...).

Use Pillow ImageGrab when its platform options fit

PIL.ImageGrab.grab() captures the screen by default and accepts a bounding box for a region. Its documentation says the returned image pixels are RGBA on macOS and RGB on other platforms. Windows supports the all_screens option. The window argument can target a Windows HWND in Pillow 11.2.1 and later, or a macOS CGWindowID in Pillow 12.1.0 and later. Confirm the installed Pillow version and test the exact target OS before relying on those newer arguments.

On Linux, the ImageGrab documentation describes fallback use of gnome-screenshot, grim, or spectacle if the default X11 display does not return a snapshot and those utilities are installed.

Whole-screen capture is not hidden-window capture

Most straightforward screen-capture examples return pixels from a display or a region of it. They do not mean that a window obscured by another window will be captured as if it were visible, nor that a service can read a desktop it cannot access. If you need a particular application window, Pillow’s documented window option is a platform- and version-specific route for Windows and macOS; verify those requirements and test on the target machine. For other cases, establish whether the application or operating system offers an appropriate window-rendering or automation interface. Do not treat a background process alone as a way to reveal hidden content.

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

Keep unattended captures reliable

Use a stable output location and deliberate filenames

Resolve the destination to an absolute path, create its parent directory, and ensure the scheduled account can write to it. Decide whether each run should replace one file or create a dated sequence. MSS’s examples include handling the case where a screenshot filename already exists; apply an explicit overwrite or retention policy in your own job as well.

Reuse capture resources for recurring work

If a task takes multiple screenshots, follow MSS’s guidance to reuse its MSS instance. This avoids repeatedly setting up the capture object. The available documentation does not establish a universal performance winner among PyAutoGUI, MSS, and ImageGrab, so measure capture duration and output handling on the hardware and display configuration that will actually run the job.

PyAutoGUI’s documentation gives an illustrative example of roughly 100 milliseconds for a screenshot on a 1920 × 1080 screen. That is the documentation’s example, not an independent cross-library benchmark or a guarantee for other machines, platforms, or workloads.

Decide what happens when capture fails

For a scheduled job, make failures observable: log the exception and destination path, and have the scheduler or monitoring system report nonzero exits according to your environment. Do not report success merely because the Python process started; check that the output exists and is non-empty. For repeated captures, consider how your job should handle a temporary display outage, unavailable output directory, or filename collision without silently discarding an earlier image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

Symptom Likely cause What to check or change
Works in a terminal, fails as a service The service account or session lacks access to the graphical display, or has a different environment. Run under the same account and session as the scheduled job; on Linux inspect DISPLAY and display access.
Linux capture reports a missing dependency or cannot capture The required capture utility or display backend is not available in that environment. Check the current PyAutoGUI installation guidance, including its documented scrot dependency, or use an appropriate supported capture setup. For ImageGrab’s documented Linux fallbacks, verify that the relevant utility is installed.
No file appears where expected The process has a different working directory, the parent directory is missing, or the account cannot write there. Use an absolute destination path, create its parent directory, and test write permissions as the service account.
The saved image shows the wrong area or monitor Region coordinates or monitor selection do not match the target display. Verify the coordinate origin, rectangle bounds, and selected monitor in the target session.
A window capture argument is rejected The installed Pillow version or operating system does not support that argument. Check the documented version-specific support: Windows window support from Pillow 11.2.1 and macOS support from 12.1.0; test on the actual target.
Later screenshots replace earlier ones The script writes the same filename on each run. Use a timestamped or unique filename, or explicitly choose a one-file overwrite policy.

Or skip the browser setup

If what you actually need is a screenshot of a web page rather than pixels from the desktop, ScreenshotNeo provides a website screenshot API and MCP server. This avoids configuring a browser and graphical desktop session for that web-page capture. Its API can return a PNG, JPEG, WebP, or PDF; see the ScreenshotNeo site and API documentation.

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)

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before the shot; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, with response headers identifying the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month without a card.

Frequently Asked Questions

Can a Python screenshot script run without a logged-in desktop?

Not by assuming that a desktop is available. The process needs access to the display it is meant to capture; test the exact account, session, and environment used in production.

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

Can PyAutoGUI save directly to a PNG file?

Yes. Pass the filename to pyautogui.screenshot(); the call saves the image and returns a Pillow image object.

Does a full-screen screenshot include a window covered by another window?

A screen capture represents display pixels; it does not inherently reveal the covered contents of a hidden window. Window capture is a separate, platform-specific feature.

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.