Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →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.
The APIs used here are documented in the Selenium Python WebDriver reference and Python’s Tkinter documentation.
#1 Best Overall
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.
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:
Rank #2
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:
- Capture PNG bytes with Selenium.
- Wrap the bytes in an in-memory stream.
- Decode the stream with an image-processing library.
- Convert the decoded image to a Tk-compatible image object.
- 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.
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:
- The button callback starts a worker for
driver.get()andsave_screenshot(). - The worker reports success or an exception to the application.
- The GUI schedules an update with its event mechanism after the worker finishes.
- 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.
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.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →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.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFix: move the long operation to a worker and schedule only the final widget update on the GUI event mechanism.
Best Value
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.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.
Recommended Free Tools
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
PhotoImagewhen 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.
Quick Recap
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.

