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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Capture the browser with Selenium, load the resulting PNG into tkinter.PhotoImage, and assign that image to a widget such as Label. Keep a live Python reference to the PhotoImage; otherwise Tk may remove the image and the label will appear blank. The file-based method below is the smallest dependable implementation when Tk 8.6 or newer is available.

Complete working example

Install Selenium and ensure a browser and its WebDriver are available for your selected browser. Selenium 4’s Python WebDriver exposes save_screenshot(), which writes a PNG and returns a Boolean success value. The following program navigates first, saves the image, checks the result, then starts the Tkinter event loop.

import tkinter as tk
from selenium import webdriver

root = tk.Tk()
root.title("Selenium screenshot")

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    saved = driver.save_screenshot("capture.png")
    if not saved:
        raise OSError("Could not save screenshot")

photo = tk.PhotoImage(file="capture.png")  # Requires Tk 8.6+ for PNG
label = tk.Label(root, image=photo)
label.image = photo  # Retain the reference while the label is visible
label.pack()

root.mainloop()

The with block closes Selenium after the capture. It does not close the Tkinter window, which continues running at mainloop(). Replace webdriver.Chrome() with the driver constructor for the browser you have configured.

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.

The APIs used here are documented in the Selenium Python WebDriver reference and Python’s Tkinter documentation.

How the handoff works

1. Selenium produces PNG data

save_screenshot(filename) writes the current browser window to a file. Selenium also provides get_screenshot_as_file(filename); it returns False when the file cannot be written, so check that result before attempting to display the image. For applications that need the bytes directly, get_screenshot_as_png() returns PNG bytes and get_screenshot_as_base64() returns a base64 string.

2. Tkinter creates an image object

tk.PhotoImage(file="capture.png") creates a full-color Tk image that widgets can render. Native PNG loading depends on Tk 8.6 or later, not merely the Python version. A Python installation can therefore be current while its linked Tk runtime is too old.

3. A widget displays the object

Pass the image with image=photo when constructing a Label, or assign it later with label.configure(image=photo). The image object must remain referenced. Storing it as label.image, as in the example, is a simple way to keep it alive.

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

File-based versus in-memory display

Approach Advantages Trade-offs Best fit
Save PNG, then PhotoImage(file=...) Few dependencies; easy to inspect and troubleshoot Creates an intermediate file and requires a writable path Most desktop utilities and first implementations
Use get_screenshot_as_png() Avoids an intermediate file; convenient for transient previews PNG bytes must be decoded into an image Tk can display Apps that should not write capture files
Decode with a third-party image library Can support additional formats and transformations such as resizing Adds a dependency and another compatibility layer Workflows requiring scaling, conversion or format support beyond native Tk

The file route is normally the clearest because each stage can be checked independently: confirm Selenium wrote the file, then confirm Tk opened it.

Displaying PNG bytes without a temporary file

driver.get_screenshot_as_png() gives you the documented binary PNG payload:

png_bytes = driver.get_screenshot_as_png()

Tk’s native PhotoImage interface is not a general-purpose byte decoder for every Python byte sequence. A common implementation uses Pillow to read BytesIO(png_bytes) and then creates an ImageTk.PhotoImage. Because Pillow’s current API and supported versions can change, check the Pillow documentation for the version you install before treating that path as a fixed interface. The conceptual flow is:

  1. Capture PNG bytes with Selenium.
  2. Wrap the bytes in an in-memory stream.
  3. Decode the stream with an image-processing library.
  4. Convert the decoded image to a Tk-compatible image object.
  5. Keep that object referenced on the widget or application.

If you do not need resizing or conversion, writing a PNG and using native Tk avoids this extra dependency.

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

Making the window responsive

Browser navigation and screenshot capture can take long enough to stop a Tkinter window repainting if they run directly inside a button callback. Put the slow Selenium work outside the GUI event loop, then deliver the result back to the GUI through its event mechanism. Keep all widget creation and updates in the GUI thread; use a worker for navigation and file generation, and have the worker schedule a callback that loads the completed file.

A practical design is:

  1. The button callback starts a worker for driver.get() and save_screenshot().
  2. The worker reports success or an exception to the application.
  3. The GUI schedules an update with its event mechanism after the worker finishes.
  4. The update callback creates the PhotoImage, assigns it to the label, and stores the reference.

This keeps the interface usable while a page loads. Exact thread-safety behavior depends on the Tk and Python builds you deploy, so validate the design on each supported platform rather than assuming every Tk call is safe from a worker.

Handling large screenshots

A full browser window can be larger than the available desktop. The basic example displays the image at its captured size; it does not automatically scale or scroll it. If the image extends beyond the window, add a scrollable canvas or resize the bitmap before creating the Tk image. Resizing belongs in an image-processing layer when you need controlled dimensions or quality settings. Preserve the resized image object just as you would the original.

Common errors and fixes

The label is blank

Cause: the PhotoImage object went out of scope, so Tk deleted the underlying image.

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

Fix: retain it on the widget or application, for example label.image = photo. Do not rely only on a temporary local variable.

Tk reports an unsupported image format

Cause: the Tk runtime is older than 8.6, or the file is not actually a valid PNG.

Fix: verify the Tk version bundled with your Python installation and confirm that Selenium’s save call returned success. Use a compatible decoder when your required format is not supported natively.

save_screenshot() raises an I/O error or returns failure

Cause: the destination directory does not exist, is read-only, or the process lacks permission.

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

Fix: use an absolute path in a writable directory, create the directory before capture, and check the Boolean result before loading the file. Never attempt to display a file that was not successfully written.

The browser opens but the capture is incomplete

Cause: the page has not finished navigating or rendering when the screenshot is taken.

Fix: wait for the page condition your application requires before calling the screenshot method. For dynamic sites, wait for a specific element or state rather than adding an arbitrary delay whenever possible.

The application freezes while capturing

Cause: navigation and capture are running synchronously in the Tk event loop.

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

Fix: move the long operation to a worker and schedule only the final widget update on the GUI event mechanism.

The screenshot path works from a terminal but not when launched from an IDE

Cause: relative paths are resolved against the process’s current working directory, which may differ between launch methods.

Fix: log or inspect the absolute destination path and build it from a known application directory or temporary-directory location.

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 you only need a rendered image or PDF and do not need to control a local Selenium session, ScreenshotNeo provides a single HTTP request. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; 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 result with X-Page-Verdict and X-Billed headers. It also offers an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

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

Use the API directly from a shell:

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(`HTTP ${res.status}`);

See the ScreenshotNeo documentation for authentication and the 63 capture options, including full-page lazy-image loading, CSS-selector element capture, device presets, retina scale, PDF controls, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, timezone and geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous webhooks, bulk capture and usage reporting. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Choosing the right implementation

  • Choose native PhotoImage when you control the desktop runtime, capture PNG, and want minimal dependencies.
  • Choose an in-memory decoder when avoiding temporary files or applying transformations is important.
  • Use a worker for any navigation or capture that could delay repainting.
  • Validate the save result, image format and object lifetime before investigating more complex GUI code.

Frequently Asked Questions

Can Tkinter display Selenium JPEG or WebP directly?

The documented native path here is PNG with Tk 8.6 or newer. Convert other formats with an image-processing library before creating the Tk image object.

Does closing WebDriver close the Tkinter window?

No. The WebDriver context ends the browser session; Tkinter remains active until its event loop exits.

Which Selenium method should I use for a preview?

Use save_screenshot() for the simplest file handoff, or get_screenshot_as_png() when your application already has an in-memory decoding path.

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.

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.