Nodes/ComfyUI Impact Pack/Preview Bridge (Image)
ComfyUI Node Runs on cloud

Preview Bridge (Image)

Preview a result and paint a mask on it, mid-graph

By ltdrdata·Created 3 years ago·Updated 4 months ago· 3,242
Preview Bridge (Image)
  • images
  • IMAGE
  • MASK
image
blockfalse
restore_mask

Preview Bridge (Image) is two things at once: a preview node that shows you an image mid-workflow, and a mask editor you can draw on right there without leaving the graph. Right-click it, open ComfyUI's MaskEditor, paint over the part you want, and the mask flows straight out of the node into whatever's downstream. It's how you do "look at this, then tell me where to fix it" as a single node instead of a save-edit-reload dance.

This is the beating heart of interactive inpainting in ComfyUI. The usual masking pain is that ComfyUI's graph doesn't have a natural place to paint - most workflows either mask externally or bolt on an awkward canvas. Preview Bridge puts the MaskEditor inline: run the graph, see the generated image on the node, paint a mask on the image you're actually looking at, and re-run with that mask feeding an inpaint or a detailer. The "bridge" in the name is literal - image data passes through, and a mask you draw comes out the side.

How it works

The image you feed in is displayed on the node (that's the preview half). When you open the MaskEditor from its right-click menu and paint, the node stores that mask and emits it on its MASK output while passing the image through on IMAGE. Because the mask is tied to the node, it persists across runs until you change it - so you can paint once and keep iterating on the same region. The node is also an output node, meaning it renders in the UI as part of a normal run rather than needing a separate preview.

The inputs and outputs that matter

  • images (required) - the image to preview and mask. This is what shows up on the node.
  • image - an internal string the node uses to track the stored/painted image; you generally don't touch it by hand.
  • block (optional, default false) - a safety gate. Set it and, per the node's own description, execution stops when the mask is empty - so a workflow that requires a mask won't silently run on nothing. Handy when a downstream detailer would misbehave with a blank mask.
  • restore_mask (optional) - never, always, or if_same_size, controlling whether a previously stored mask is reapplied when the input changes. if_same_size is the sensible middle ground: reuse the mask if the new image matches, otherwise start clean.

Outputs: IMAGE (the image passed through, ready for an inpaint or detailer) and MASK (what you painted, ready for the mask input of that same node).

How to install it

Install the pack via ComfyUI Manager (search ComfyUI Impact Pack, install, restart), or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/ltdrdata/ComfyUI-Impact-Pack comfyui-impact-pack
cd comfyui-impact-pack
python -m pip install -r requirements.txt   # ComfyUI's python; python_embeded on portable

then restart. No models. One caveat worth knowing: PreviewBridge relies on features from a reasonably modern ComfyUI - very old builds (pre-July 2023) don't render it correctly - so if the editor doesn't open, update ComfyUI first.

Common issues & troubleshooting

I painted a mask but downstream got nothing. Make sure you're wiring the node's MASK output onward, not expecting the mask to travel with the image. And confirm the mask actually saved - after painting in the MaskEditor you have to apply/save it back to the node, not just close the dialog.

The old mask keeps coming back on a new image. That's restore_mask set to always. Switch it to if_same_size or never so a new image doesn't inherit the previous region.

My workflow ran on an empty mask and produced garbage. Turn on block. It halts execution when the mask is empty, which is exactly the guard you want in front of a detailer or inpaint that assumes a mask exists.

There's also a latent version. If you're masking in latent space (for a mask stored on a latent, which the MaskEditor can set), that's PreviewBridge (latent) - same idea, latent in and out, with the mask read from and written to the latent.

CategoryImpactPack/Util

Inputs (4)

NameTypeDefaultDescription
imagesIMAGE
imageSTRING
blockoptBOOLEANfalseis_empty_mask: If the mask is empty, the execution is stopped. never: The execution is never stopped.
restore_maskoptCOMBOif_same_size: If the changed input image is the same size as the previous image, restore using the last saved mask always: Whenever the input image changes, always restore using the last saved mask never: Do not restore the mask. `restore_mask` has higher priority than `block`

Outputs (2)

NameTypeDescription
IMAGEIMAGE
MASKMASK