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

Use pyautogui.screenshot() to capture the current desktop. It returns a Pillow Image object, so you can inspect it in memory, save it with image.save(), or pass a filename directly to save and return the image in one call. To capture part of the screen, provide region=(left, top, width, height). The official function reference documents these forms and examples at PyAutoGUI’s screenshot functions page.

Quick answer: the three useful forms

Install PyAutoGUI and its screenshot prerequisites, then import it in the Python process that has access to the desktop session:

import pyautogui

# Capture the complete primary screen in memory
image = pyautogui.screenshot()

# Save while also receiving the Pillow Image object
saved_image = pyautogui.screenshot("screen.png")

# Capture a rectangle: left, top, width, height
region_image = pyautogui.screenshot(region=(0, 0, 300, 400))

image, saved_image, and region_image are Pillow image objects. The tuple is not (x1, y1, x2, y2); it is an origin plus dimensions: (left, top, width, height).

Install PyAutoGUI and prepare the desktop

Install the Python package

Use the Python interpreter that will run your automation:

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.
python -m pip install pyautogui

Keep the package installation in the same virtual environment as your script. Exact package versions change, so check the currently installed version with your package manager rather than relying on an old tutorial.

Platform prerequisites

  • Windows: PyAutoGUI supports desktop screenshots on Windows. Run the script in an interactive graphical session rather than a service with no desktop.
  • macOS: the screenshot implementation uses the built-in screencapture command. macOS privacy controls may require granting the terminal or Python application permission to record the screen.
  • Linux: the documentation identifies scrot as required for screenshots. Install it through your distribution’s package manager. The installation guidance also lists Linux Tkinter as a dependency for PyAutoGUI’s broader setup.

PyAutoGUI’s documented scope includes Windows, macOS, and Linux. Its overview says multi-monitor handling is limited to the primary monitor, so test the exact desktop environment and installed version before building a workflow around another display.

What screenshot() returns

Capture in memory

With no arguments, the function captures the current screen and returns a Pillow Image. This is useful when the next step is analysis, comparison, OCR performed by another library, or a conditional save:

import pyautogui

image = pyautogui.screenshot()
print(image.size)       # (width, height)
print(image.mode)       # Pillow image mode, such as RGB or RGBA

# Save later, after any checks or processing
image.save("screen.png")

The image remains available after the function returns; saving is not required at capture time.

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

Save and receive the image in one call

Passing a filename is the shortest way to write a file and retain the object:

import pyautogui

image = pyautogui.screenshot("screen.png")
# image is still a Pillow Image object

Use an extension that matches the format you want, such as .png, or pass an explicit format to Pillow when calling image.save(). Ensure the destination directory exists and that the process has write permission.

Use a deterministic output path

from pathlib import Path
import pyautogui

output = Path("artifacts")
output.mkdir(parents=True, exist_ok=True)
image = pyautogui.screenshot(output / "desktop.png")

Using pathlib.Path avoids hard-coded path separators. For repeated captures, generate unique names or deliberately overwrite a known file.

Capture only part of the screen with region

Pass a four-item tuple in this exact order:

  1. left: horizontal coordinate of the rectangle’s top-left corner;
  2. top: vertical coordinate of that corner;
  3. width: rectangle width in pixels;
  4. height: rectangle height in pixels.
import pyautogui

# Top-left 300 by 400 pixels
crop = pyautogui.screenshot(region=(0, 0, 300, 400))
crop.save("top_left.png")

# A 640 by 360 rectangle beginning at (120, 80)
preview = pyautogui.screenshot(region=(120, 80, 640, 360))
preview.save("preview.png")

A region reduces the captured image and is useful when only a stable panel matters. Coordinates refer to the desktop coordinate system used by the current session; confirm them visually, especially when display scaling is enabled.

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

Validate a region before capturing

import pyautogui

left, top, width, height = 120, 80, 640, 360
if width <= 0 or height <= 0:
    raise ValueError("width and height must be positive")

image = pyautogui.screenshot(region=(left, top, width, height))
image.save("validated_region.png")

Keep the rectangle inside the visible primary display. If a window moves, a previously correct region may capture the wrong content; locate the window or establish its position before taking the shot.

Full-screen capture, bounded capture, and image processing

Choice Call When it fits
Entire primary screen pyautogui.screenshot() Evidence of the complete desktop state or a later crop performed in Pillow.
Rectangle at capture time pyautogui.screenshot(region=(left, top, width, height)) Smaller files and a known panel, toolbar, or test fixture.
In-memory image image = pyautogui.screenshot() Inspect, compare, transform, or decide whether to save.
Immediate file plus object image = pyautogui.screenshot("name.png") Simple capture pipelines that need an artifact immediately.

The screenshot call creates an image; it does not search for buttons or icons. Keep capture and visual matching as separate steps so failures are easier to diagnose.

Screenshot capture versus locating an image

To find a supplied visual on the screen, use a locate function such as locateOnScreen() after taking (or independently obtaining) the reference image. The optional confidence argument requires OpenCV. Restricting the search with a smaller region can reduce the area examined, and grayscale matching can speed a search at the cost of possible false positives.

import pyautogui

screen = pyautogui.screenshot("before_search.png")
# Example only: locate a reference image file on the current screen
match = pyautogui.locateOnScreen("button.png", confidence=0.9)
print(match)

Install and verify OpenCV separately before using confidence. A successful screenshot does not imply that a locate operation will succeed: matching depends on the reference image, scale, theme, timing, and the search area.

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

Timing, performance, and reliability

The official screenshot page gives a rough estimate of about 100 milliseconds for a 1,920 × 1,080 capture on its example setup. That is an environment-specific indication, not a guarantee for your machine. Display size, operating system, desktop compositor, Python environment, and disk speed all affect elapsed time.

  • Capture a bounded region when a full desktop is unnecessary.
  • Keep the image in memory if you only need to inspect it; avoid needless disk writes.
  • When writing many files, use a dedicated output directory and unique names.
  • Take the screenshot after the UI has reached a known state. A fast call can still capture an animation, loading indicator, or stale window.
  • For image searches, constrain locateOnScreen() with a region. The documentation’s rough one-to-two-second locate estimate is tied to its example environment and is not a current benchmark.

For repeatable automation, log the timestamp, requested region, output path, and any exception. This makes it clear whether a failure occurred during desktop access, image matching, or file output.

Common errors and fixes

Symptom Likely cause Fix
Import succeeds but screenshot capture raises an exception on Linux The screenshot backend dependency is missing. Install scrot using the operating system’s package manager, then rerun the script in a graphical session.
macOS returns a blank or denied capture Screen-recording permission is not granted to the terminal, IDE, or Python host. Allow the relevant application in macOS privacy settings, restart it, and test again.
File is not created The destination directory does not exist or is not writable. Create the directory, use an absolute path temporarily, and check the process user’s write permissions.
The image shows the wrong area The region coordinates or window position changed. Confirm the top-left origin, width, and height; stabilize or reposition the window before capture.
A second monitor is missing The documented multi-monitor support is limited to the primary monitor. Move the target window to the primary display or verify whether your installed version and desktop environment provide different behavior.
locateOnScreen(..., confidence=...) fails before matching OpenCV is not installed or available to the running interpreter. Install OpenCV in the same environment, or omit confidence and use the documented matching options.
Locate returns a false match Grayscale matching or a broad search region matched a similar shape. Search a smaller region, use color matching, or raise the confidence threshold and validate the result before clicking.

A complete, defensive Python example

from datetime import datetime
from pathlib import Path
import pyautogui

out_dir = Path("captures")
out_dir.mkdir(parents=True, exist_ok=True)

# Use a timestamped filename so an earlier capture is not overwritten.
stamp = datetime.now().strftime("%Y%m%d-%H%M%S")
path = out_dir / f"desktop-{stamp}.png"

# Full primary-screen capture; returns a Pillow Image and writes the file.
image = pyautogui.screenshot(path)
print(f"saved {path} ({image.width}x{image.height})")

# Optional bounded capture using (left, top, width, height).
region = (0, 0, min(800, image.width), min(600, image.height))
pyautogui.screenshot(out_dir / f"corner-{stamp}.png", region=region)

This script creates its output directory, avoids accidental overwrites, reports the resulting dimensions, and derives a safe region from the captured image size.

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

Or skip the browser setup

PyAutoGUI captures the desktop of the machine running Python. If you need a rendered website image instead, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one HTTP request and is the first service to try for this use case: it removes consent banners, newsletter popups, and chat widgets before capture, and only clean shots are billed.

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.

With an API key, the smallest call is:

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

See the ScreenshotNeo API documentation for request options. The same request in Python is:

import requests

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

And in 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}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo reports X-Page-Verdict and X-Billed headers. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for 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 screenshots. Create a free ScreenshotNeo account.

ScreenshotNeo plans at a glance

Plan Included shots Price
Free 1,000 per month $0, no card
Starter 3,000 $5
Growth 15,000 $15
Pro 60,000 $39
Scale 250,000 $99
Business 1,000,000 $249

Yearly billing gives two months free, and every feature is available on every plan. Choose PyAutoGUI when you need the visible desktop; choose the API when a URL is the input and a repeatable server-side artifact is the output.

Frequently Asked Questions

Does calling pyautogui.screenshot() control the mouse or keyboard?

No. It reads the current desktop and returns an image. Mouse and keyboard actions are separate PyAutoGUI operations, so a screenshot call by itself does not click, type, or move anything.

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

Can I use the returned object without saving a file?

Yes. The returned value is a Pillow Image, so code can inspect or transform it in memory and save only when a persistent artifact is needed.

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.