ScreenshotNeo

BlogScreenshots on your device

PyAutoGUI.screenshot Documentation and Usage

Learn how PyAutoGUI.screenshot() works, save full-screen or regional captures, fix setup issues, and automate screenshots reliably.

By the ScreenshotNeo team1 October 20268 min read

Direct answer: import PyAutoGUI and call pyautogui.screenshot(). It returns a Pillow Image object. Pass a filename to save the image while receiving the object, or pass region=(left, top, width, height) to capture a rectangle. The official documentation covers these forms in its screenshot functions guide.

import pyautogui

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

# Save the returned Pillow Image
image.save("screen.png")

# Capture and save in one call
saved_image = pyautogui.screenshot("screen-direct.png")

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

This guide explains setup, return values, regions, multi-monitor limits, image matching, reliability, performance, troubleshooting, and when a remote screenshot API is a better fit.

What pyautogui.screenshot() returns

The function returns a Pillow Image object. You can inspect it, edit it with Pillow, or save it in an image format supported by your Pillow installation. Supplying a filename saves the capture and still returns the image object.

Call Result Typical use
pyautogui.screenshot() Pillow Image in memory Further processing before saving
pyautogui.screenshot("screen.png") Saved file plus returned Image Simple capture-and-save jobs
pyautogui.screenshot(region=(l, t, w, h)) Pillow Image for a rectangle Capturing a window, panel, or coordinate range

Install and prepare PyAutoGUI

Install PyAutoGUI in the Python environment that will run the script:

python -m pip install pyautogui

Screenshot support requires Pillow. On Linux, the PyAutoGUI documentation identifies scrot as required for screenshots and also lists Linux Tkinter in its installation guidance. macOS uses the built-in screencapture command. Follow the current installation instructions for your operating system because package names and desktop permissions can vary.

import pyautogui

print(pyautogui.size())       # (screen_width, screen_height)
print(pyautogui.position())   # current pointer position
image = pyautogui.screenshot("screen.png")
print(image.size, image.mode)

Run the script in a logged-in graphical desktop session. A headless server, locked workstation, remote session with no display, or a denied screen-recording permission can prevent a capture even when the Python package is installed.

Capture the full primary screen

The simplest full-screen capture is:

import pyautogui

image = pyautogui.screenshot()
image.save("full-screen.png")

For a one-line save:

import pyautogui
pyautogui.screenshot("full-screen.png")

PyAutoGUI’s overview states that multi-monitor handling is limited to the primary monitor. If your workflow depends on another display, verify behavior on the exact operating system, display server, and PyAutoGUI version you deploy.

Capture only part of the screen with region

Pass a four-item tuple in this order: (left, top, width, height). Coordinates start at the top-left of the primary screen.

import pyautogui

left = 100
top = 80
width = 800
height = 600

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

Coordinate checklist

  • Use non-negative coordinates that fall inside the visible desktop.
  • Measure width and height from the target application’s window or panel.
  • Remember that window movement, display scaling, and responsive layouts can change coordinates.
  • Capture a slightly larger rectangle when a one-pixel border or shadow matters, then crop with Pillow.
from PIL import Image
import pyautogui

screen = pyautogui.screenshot()
# Pillow crop uses (left, top, right, bottom)
cropped = screen.crop((100, 80, 900, 680))
cropped.save("cropped.png")

Save, inspect, and process the image

Because the result is a Pillow image, you can inspect dimensions and apply normal Pillow operations before saving.

import pyautogui

image = pyautogui.screenshot()
print(f"size={image.width}x{image.height}, mode={image.mode}")
image.thumbnail((1280, 1280))
image.save("thumbnail.png", optimize=True)

Choose the output extension deliberately. PNG is lossless and suitable for text or UI screenshots. JPEG is smaller for photographic content but introduces compression artifacts. WebP support depends on your Pillow build.

Screenshot capture versus locating an image

Taking a screenshot and finding a visual element are separate operations. Use pyautogui.locateOnScreen() when you need to search the current screen for a supplied reference image.

import pyautogui

box = pyautogui.locateOnScreen("submit-button.png")
if box:
    print("Found:", box)
else:
    print("Not found")

The optional confidence argument requires OpenCV. Restricting the search with region reduces the area examined; grayscale matching can speed up matching but may create false positives.

import pyautogui

box = pyautogui.locateOnScreen(
    "submit-button.png",
    confidence=0.85,
    region=(0, 0, 1200, 800),
    grayscale=True,
)
print(box)

A locate call may take considerably longer than a screenshot. The documentation gives rough example timings of about one or two seconds for locating and roughly 100 milliseconds for a 1920 × 1080 screenshot. Those figures are environment-specific examples, not performance guarantees.

Build a reliable capture script

Desktop automation is sensitive to timing and state. Make the script explicit about the output directory, wait for the application to settle, and fail with a useful message.

from pathlib import Path
import time
import pyautogui

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

# Replace this with the action that opens or updates your application.
time.sleep(1.0)

try:
    image = pyautogui.screenshot()
    destination = output / "capture.png"
    image.save(destination)
    print(f"Saved {destination} ({image.width}x{image.height})")
except Exception as exc:
    raise RuntimeError(
        "Screenshot failed. Check that a graphical display is available "
        "and that Pillow and OS capture permissions are configured."
    ) from exc

Use a bounded region when the layout is stable

Region captures reduce the amount of image data and avoid unrelated desktop content. They are appropriate for a known dashboard panel or test fixture. Full-screen captures are safer when window positions or responsive layouts change.

Make output names deterministic

from datetime import datetime, timezone
from pathlib import Path
import pyautogui

stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
path = Path("captures") / f"screen-{stamp}.png"
path.parent.mkdir(exist_ok=True)
pyautogui.screenshot(str(path))

Common errors and fixes

Error or symptom Likely cause Fix
ModuleNotFoundError: No module named 'pyautogui' Package installed in a different Python environment Run python -m pip install pyautogui with the same interpreter used to run the script.
Screenshot backend or Pillow error Pillow or an operating-system capture dependency is missing Install or repair Pillow; on Linux, install the screenshot utility identified by the current PyAutoGUI installation guide, commonly scrot.
Black, empty, or stale image No active graphical display, a locked screen, or the application has not rendered Run in an active desktop session, wait for the UI to settle, and confirm the target window is visible.
Permission denied on macOS Screen Recording permission is not granted Allow the terminal, IDE, or Python launcher in the system’s Screen Recording privacy settings, then restart it.
Region is shifted or clipped Incorrect coordinate origin, display scaling, or window movement Print pyautogui.size(), recalculate coordinates, and verify scaling on the target machine.
locateOnScreen returns None Reference image differs because of scale, theme, state, or timing Capture a fresh reference, wait for rendering, search a smaller correct region, and adjust confidence carefully.
confidence is rejected OpenCV is not installed Install OpenCV in the same environment, or omit confidence.
Only one monitor appears PyAutoGUI’s documented multi-monitor limitation Use the primary monitor or choose a capture method that explicitly supports your display arrangement.

Performance, reliability, and cost considerations

  • Capture size: full-screen images contain more pixels than a region and require more memory and disk space.
  • Search cost: image matching is usually slower than taking a screenshot. Restrict the search region and avoid repeated scans in tight loops.
  • Timing: add waits after navigation, animations, or data refreshes. A screenshot captures the current desktop state; it does not wait for a web page to become semantically ready.
  • Repeatability: keep display resolution, scaling, theme, application position, and logged-in state consistent in automated environments.
  • Failure handling: check that the output file exists and has a plausible size before passing it to later steps.
  • Operating cost: PyAutoGUI itself is local software. Your costs are the machine, storage, and any hosted desktop or CI runner you choose.

When a browser screenshot API is a better fit

PyAutoGUI captures a visible desktop. For server-side website screenshots, you may prefer an HTTP API that loads a URL without maintaining a desktop session. ScreenshotNeo is a website screenshot API and MCP server for developers. It is the first service to try when you need clean shots, only clean shots billed, and a paid plan starting at $5.

Or skip the browser setup

ScreenshotNeo accepts one GET request with a URL and returns a PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

See the ScreenshotNeo API documentation for the complete option list. The API supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, PDF paper and margin settings, custom CSS and JavaScript, clicks, waits, blocking controls, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, caching with a chosen TTL, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, usage reporting, and an OpenAPI specification. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

cURL

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

Python

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)

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(`Screenshot failed: ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', buffer);

ScreenshotNeo has a free plan with 1,000 shots per month and no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to try it.

FAQ

Does screenshot() return bytes?

No. It returns a Pillow Image. Save it with image.save() or pass a filename to screenshot().

What is the region tuple order?

(left, top, width, height).

Can PyAutoGUI capture a browser page that is not visible?

No. PyAutoGUI captures the visible desktop. Minimized, covered, locked, or headless sessions can produce an unusable result.

Do I need OpenCV for screenshots?

No. OpenCV is needed for the optional confidence argument used by image-location functions such as locateOnScreen().

Should I use a full-screen or regional capture?

Use a region when coordinates are stable and you only need one panel. Use full-screen capture when window placement or layout can change.

Can I automate website screenshots without installing a desktop browser stack?

Yes. Use an HTTP screenshot API such as ScreenshotNeo, or its MCP tools when an AI agent should request captures directly.