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


