🖥️ Preview Image Monitor
Put Your Outputs on a Second Screen Without Alt-Tabbing
- images
- compare_image
- images
Here's the workflow that makes this node click: you're running long batches or a slow upscale, you don't want to keep tabbing back into the ComfyUI browser tab to check every frame, and you definitely have a spare monitor that's just showing wallpaper. Preview Image Monitor pops a persistent fullscreen window onto any display you pick and keeps it updated every time your queue runs. It's the image half of the preview-monitor family that NicLandajo's repos made popular - one of those "I didn't know I needed it until I had it" nodes.
How it works
The mechanism is simple but genuinely useful: the node takes your IMAGE tensor, converts it to PIL, and hands it to a pygame window that lives in a background thread. The window doesn't close between runs - re-run your graph and the new result slides in, which is the entire point. You're effectively getting a live render monitor that ComfyUI's own browser preview can't give you.
The smart part is performance. With fps_mode set to smart (the default), the window only redraws when something actually changed - the code hashes the current image and compares it against what's on screen, and skips the redraw if both the image and your settings are untouched. Idle windows cost you almost nothing. Fixed 15/30 fps modes exist if you want constant redraws, but you won't need them.
You also get two display modes beyond plain single. Comparison overlays your image against the optional compare_image input with a mouse-controlled split line - great for A/B-ing a before/after or a LoRA on/off without squinting at side-by-side thumbnails. Slideshow lets you flip through a batch with the arrow keys. Mouse wheel zooms (0.1–10x), drag pans, R resets. The window title even updates with zoom and slide position.
Inputs and outputs that matter
The full list is in the node, but a beginner mostly touches these:
images(required) - your IMAGE tensor. Wire this from your VAE decode/upscale output.display_mode-single,comparison, orslideshow.monitor- pick which display to use. Entries show(unknown resolution)when screeninfo can't read your setup; installingscreeninfofixes that.power_state- set toOffto gracefully shut the window down.fit_mode-fit(default) letterboxes;fillcrops to fill;distortstretches;centerandnonekeep native pixels.gain,gamma,saturation- on-screen-only color trims (0–10, default 1). Handy when a model outputs something too dark to judge.fps_mode,white_matte, and the optionalcompare_imageround it out.
The single output is images, which is just your input passed straight through - it's an output node, so it acts as the last stop in your graph and the passthrough keeps the batch flowing if you chain anything after it.
Installing it
No model downloads, no API keys, no heavy deps - this one needs nothing but a display to show on. Easiest route is ComfyUI Manager: search for "ComfyUI Preview Monitor" and hit install. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/xhh522/ComfyUI-preview-monitor
cd ComfyUI-preview-monitor
pip install -r requirements.txt
Then restart ComfyUI. requirements.txt pulls in pygame, Pillow, and numpy; screeninfo is the optional extra that makes multi-monitor detection report real resolutions instead of "unknown resolution".
Gotchas
The big one: pygame is not optional in practice. If it's missing, the node logs "cannot display preview" and just passes your images through - silent, and easy to miss if you're not watching the console. And while the README bills a Web mode, this node is pygame through and through; it needs a real local display, so a headless server won't show anything.
Two behavior quirks worth knowing. Switching monitor force-closes any window on another display (only one window per monitor), and hitting ESC hides the window but leaves the thread alive - that's by design, so your next queue run just brings it back. Press H in the window for the full control cheat sheet. This is a niche tool, but if you've ever wanted ComfyUI's output on the big screen, it's the cheapest way to get there.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| monitor | COMBO | Monitor 0 (unknown resolution) | 6 options: Monitor 0 (unknown resolution), Monitor 1 (unknown resolution), Monitor 2 (unknown resolution), Monitor 3 (unknown resolution), Monitor 4 (unknown resolution), Monitor 5 (unknown resolution) |
| power_state | COMBO | On | 2 options: On, Off |
| display_mode | COMBO | single | 3 options: single, comparison, slideshow |
| fit_mode | COMBO | fit | 7 options: none, width, height, fit, fill, distort, +1 |
| target_resolution | COMBO | 1920x1080 | 2 options: 1920x1080, 3840x2160 |
| gain | FLOAT | 1.00–10 | — |
| gamma | FLOAT | 1.00–10 | — |
| saturation | FLOAT | 1.00–10 | — |
| white_matte | BOOLEAN | false | — |
| fps_mode | COMBO | smart | 3 options: smart, 15fps, 30fps |
| compare_imageopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |