LC Preview Mask ๐ญ
Check the matte without killing the queue over a null
- 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.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| maskopt | MASK | Mask to show (white = masked). Nothing connected or a null signal is fine: the node just waits. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | โ |