Image Filter
Generate eight, keep two, upscale only those
- images
- latents
- masks
- images
- latents
- masks
The oldest missing feature in ComfyUI
People have been asking how to pick the good frames out of a batch before the expensive half of the workflow since 2023, and every answer was a workaround: two Save Image nodes and a manual drag-back to reload the workflow, or a "hold" trick on someone's efficient sampler that nobody could explain twice. What you want is obvious - pause, show me what you made, let me click the keepers, then upscale and detail only those.
Image Filter is that node: it blocks execution, opens a full-screen picker, and only what you select continues down the graph. And it passes the images onward, so it's a real junction rather than a dead end.
How it works
The mechanism explains every quirk. The node declares itself list-in / list-out, flattens every incoming image (a single image, a batch, or a list - batches get split so each frame is individually clickable), writes temp previews of all of them through ComfyUI's own PreviewImage save path, and pushes an event to your browser. Then it blocks the worker thread on that event, polling ComfyUI's interrupt flag every quarter second so the queue's Cancel button still works while it waits. When you hit Send, the dialog POSTs your picked indices back and the node continues with those images.
Two details fall out of that. It asks on every run, even when nothing upstream changed - an always-dirty node by design. And because everything upstream is still cached, the node's Run again button re-asks you about the same images instead of regenerating them. That's the iterate-on-a-batch loop.
The fields that matter
Only a handful, and the defaults are mostly sane:
timeout- how long to wait for an answer (default600, ten minutes; max 86400). The dialog counts down and has a Reset timer button, so a long pick session doesn't get sniped mid-decision.on_timeout- what to send when nobody answers:send none,send all,send first,send last.on_single- what to do when exactly one image arrives. Defaultsend through, meaning it stays out of your way.on_none- what happens when nothing comes out. It's a right-click → Properties entry rather than a widget on the node.Stop runkills the whole run;Stop branchonly skips the nodes after the filter, so a Save Image placed earlier still finishes.
Optional latents and masks inputs ride along and get filtered the same way, and the outputs are images, latents and masks - all lists, which is why a batch in comes out as a batch. The dialog is what you'd want: fit-to-screen or fixed tiles, All / None / Invert, click-order output, Enter to send, A for all, Space and the arrows in the large view, Esc back or hide. Hide it and the workflow keeps waiting; the top bar and an Open selector button on the node bring it back.
Installing it
Via ComfyUI Manager, search ComfyUI vsLinx Nodes. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/vslinx/ComfyUI-vslinx-nodes.git comfyui-vslinx-nodes
Restart ComfyUI and look under vsLinx/image, or search "image filter". No models, no pip installs - the pack declares no Python dependencies. It's a deliberate rebuild of the Image Filter node from chrisgoringe's cg-image-filter, the pack people historically tried for this and the one you find threads about when it half-works. The vsLinx version drops sound and video support and adds the timeout controls.
Common issues
You tested it with one image and it did nothing. on_single defaults to send through. The node checks for exactly one image and passes it straight on without asking. Set it to show dialog while you're still setting the thing up.
It's the biggest trap in the node: running headless. There's no browser to click, so the run waits ten minutes, applies on_timeout (default send none), and with the default on_none of Stop run the whole run fails - it looks broken rather than waiting on you. If nothing is going to click, set on_timeout to send first or send all.
Latents and masks must line up. One entry per image, in the same order. Feed them from the same batch as the images and they will; splice them from two sources and your picks get attached to the wrong latents.
Mixed-size images want a list, not a batch. A batch is a single tensor, so images of different sizes are resized to a common shape before the filter ever sees them. Feed it a list instead - the pack's own multi-image list loader is the natural source - and every image is shown and passed on at its original size.
The previews are temp files. Same as Preview Image: gone after a restart. Don't treat the picker as a gallery.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| timeout | INT | 6001–86400 | Seconds to wait for a selection before the on_timeout action is applied. |
| on_timeout | COMBO | send none | 4 options: send none, send all, send first, send last |
| on_single | COMBO | send through | What to do when only one image arrives. |
| on_none | COMBO | Stop run | 2 options: Stop run, Stop branch |
| latentsopt | LATENT | — | |
| masksopt | MASK | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| latents | LATENT | — |
| masks | MASK | — |