Nodes/ComfyUI LC123 Nodes/LC Preview Mask ๐ŸŽญ
ComfyUI Node

LC Preview Mask ๐ŸŽญ

Check the matte without killing the queue over a null

By lonecatone23ยทCreated 2 months agoยทUpdated about 7 hours agoยท 22
LC Preview Mask ๐ŸŽญ
  • mask
  • mask

Masks are the part of an image pipeline you can't debug by looking at the output. If your inpainting did nothing, if the skin grade hit the wrong thing, if the upscale patch landed somewhere odd - the answer is almost always in the matte, and the answer is almost always "it's not where you thought it was". So you wire a preview onto the mask output.

Then you mute the detection branch, and the stock mask preview dies on a null. LC Preview Mask does the same job as the core mask preview, except an absent signal is fine: nothing connected, muted branch, null, empty batch - the window stays black and the queue keeps moving.

How it works

It subclasses core PreviewImage and takes the mask input as optional, so a missing wire isn't a missing required input. If what arrives isn't a real non-empty tensor, it returns an ExecutionBlocker - which on modern ComfyUI means everything downstream is skipped quietly rather than choking on None. That's the difference between "I'm testing teal on one branch" and "my queue is red".

When there is a signal, it normalises the shape (2D HW, B1HW, BHW1), clamps to 0โ€“1, and expands it to three identical channels so the preview code can write a normal PNG. The window launches black, in the pack's standard 300-wide / 268ร—335 preview layout, because a mask preview should read as a mask at a glance.

White is masked. Black is not. Batch previews show the first frame.

Inputs and outputs

One optional input, mask. One output, mask, passed through - so you can hang this mid-pipeline and keep the mask flowing into your inpaint, your Color Match, your upscaler, whatever.

That pass-through matters more than it sounds for the LC pack's own nodes: several of them (Color Match, Tone Match, the mask-passthrough taps) treat mask=None as "full frame". So an upstream preview that happens to also be a blocker is how you deliberately turn a masked operation into a full-frame one without rewiring. A bank tap, in the pack's own language.

Install

Manager โ†’ ComfyUI LC123 Nodes, or:

cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes.git

Restart. No dependencies beyond what ComfyUI ships, no pip step, nothing to download. If the node is missing from LC123/image, your clone is nested one folder too deep. And hard-refresh the browser after updating, since the preview window itself is JS.

Common issues

All black. Two possibilities, and they're very different. Either nothing arrived - check the upstream branch really is live, and remember this node will not tell you if it isn't - or the mask genuinely is empty. The second case is the common one: a detector that found nothing, an inverted threshold, or a mask_source that didn't match your data. Compare against the source image before assuming the preview is broken.

All white. Your matte covers the whole frame. That's not necessarily wrong - several LC nodes treat a full-frame mask as "no mask at all" and behave as if nothing were wired. But if you expected a subject silhouette, your threshold or your invert is off.

Anything in the file to keep? No. Previews write to ComfyUI/temp/, the scratch directory, same as core Preview Image. If a mask is worth keeping, save it - don't count on a preview surviving a browser restart.

Soft or feathered edges look harsh in the preview. It's a display artifact of the window scaling, not the mask changing. Judge feathering on the composited output, not on the preview window, or you'll over-tune your blur radius fighting a rendering illusion.

CategoryLC123/image

Inputs (1)

NameTypeDefaultDescription
maskoptMASKMask to show (white = masked). Nothing connected or a null signal is fine: the node just waits.

Outputs (1)

NameTypeDescription
maskMASKโ€”