Easy Capture Node
Point a ComfyUI node at any window on your screen and paint in real time
- IMAGE
- MASK
Easy Capture Node does one thing: it turns any window on your screen into an image input for your graph. The name is a little misleading - it doesn't grab anything server-side and needs no API key. All the capture happens in your browser, and what reaches the node is a base64-encoded PNG. That sounds unglamorous, but it's the whole trick behind the "sketch in another app and watch Stable Diffusion follow along" real-time painting setups from late 2023, and it still works today.
It was built for one specific party trick: combine it with ControlNet and an LCM model and you get near-interactive generation. LCM needs only 4–8 steps with the LCM sampler and a CFG around 1–2, which is what made this kind of live feedback possible on a normal GPU in the first place. You paint in Krita (or any window - your editor, a video, another monitor), the captured frame becomes your ControlNet condition, and the model redraws over it fast enough to feel responsive. The README links a YouTube demo of exactly that. If you've seen those mesmerizing Krita + LCM splitscreen videos, this node is the ComfyUI-native way to get there.
How it works
When you drop the node in, it adds a widget with Start Capture and Stop Capture buttons plus a video preview. Start it and your browser asks which screen or window to share (that's the getDisplayMedia API under the hood). A red drag box lets you select the region you care about, and every ~300ms the node samples that region, encodes it as base64 PNG, and stuffs it into the node's image input. The Python side decodes that string, loads it with PIL, and emits tensors.
The whole thing is the old-school ComfyUI extension pattern: the pack's __init__.py copies its JavaScript into ComfyUI/web/extensions/FISH_EasyCapture at startup. It's janky in places - the code literally calls the render button "Rander" - but the mechanism is honest and the loop is tight enough for real-time work.
Inputs and outputs
- image (required, string) - the base64 PNG data. Normally you never touch this; the capture widget fills it. If you want to hand-feed it, use raw base64 without the
data:image/png;base64,prefix. - text (optional, string) - a force-input string hook. It's declared in the schema but the shipped
load_image()only readsimage, so it does nothing in the current code. Safe to ignore. - Outputs: IMAGE (the decoded frame as a normal 0–1 RGB tensor, batch of one) and MASK. The mask is a trap: it's
1 - alpha, so you only get anything useful from an RGBA source, and the capture path produces plain RGB - meaning you'll almost always see an all-zero 64×64 mask. Wire the IMAGE output into a ControlNet preprocessor or straight into img2img.
Installing it
There's no requirements.txt anywhere in the pack, so no extra Python dependencies - the only libraries it uses (PIL, torch, numpy) ship with ComfyUI already. That's rare and refreshing.
ComfyUI Manager: search for EasyCaptureNode or ComfyUI-EasyNode. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/zhuanqianfish/ComfyUI-EasyNode
Restart ComfyUI. The node lives under the Easy Nodes category.
Where people get burned
- Screen capture needs a secure context. The browser only lets
getDisplayMediarun onhttps://orlocalhost. If you reach ComfyUI over a plain LAN IP, the capture button will silently do nothing. - The frontend writes into ComfyUI's own
web/extensionsfolder. A ComfyUI update can wipe that folder, and the node's UI won't come back until you restart ComfyUI and the pack re-copies its files. If the capture buttons vanish, restart and reinstall. - It's a 2023 node. This pack is essentially frozen, and it shows. Modern alternatives - built-in webcam/screen feed nodes, Krita/Aseprite LCM plugins, hosted real-time tools - are smoother. But if you specifically want "feed a region of my screen into ControlNet," Easy Capture Node still does the one thing it was built for, with zero dependencies and no key.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | STRING | — | |
| textopt | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| MASK | MASK | — |