Nodes/ComfyUI-Utility-Suite/Mask Batch to Mask
ComfyUI Node

Mask Batch to Mask

Twenty Masks Into One, the Additive Way

By tom-m-2020·Created about a month ago·Updated 7 days ago· 1
Mask Batch to Mask
  • masks
  • mask

ComfyUI's mask tools really want a single mask. Inpainting takes one, most samplers take one, and the whole SEGS-to-mask-to-composite chain ends in one. But almost nothing upstream gives you one: a tiled pass produces a mask per tile, a batch pass produces one per image, a detection loop produces one per region. At some point you have to fold N masks back into one, and the question is what "fold" should mean.

This node folds them additively, clamped at 1.0 - which is the same semantics as core's MaskComposite set to add. Overlapping regions saturate instead of double-counting, and the union of everything the batch covered comes out at full strength.

How it works

Rank-2 input gets a batch dimension and passes straight through. Rank-3 input with a single item also passes through untouched, so a batch of one is free. Otherwise the node starts from the first mask and repeatedly adds the next one, clamping the result into 0-1 after each step, and returns a single [1, H, W] mask.

Clamping between steps rather than at the end is what keeps a stack of 40 soft masks from drifting into nonsense: the accumulation is bounded at every point, so the output is always a valid mask. It also means the operation is order-independent in the ways you would hope, and idempotent for hard masks - adding an already-included region changes nothing because it was already at 1.0.

What it is good at, and what it is not

For unioning detections it is exactly right. Ten face masks from a batch, three hand masks, an eye mask from a different detector - add them all and you have one mask covering every region you care about, with hard edges staying hard. Feed that to a single inpainting pass or a compositing node and you are done.

For combining soft masks it is a blunt instrument, and this is worth knowing before you conclude the node is misbehaving. Additive saturation means two feathered masks each at 0.4 produce 0.8 in the overlap, not 0.4 - so the transition zone inflates toward full coverage wherever two ramps cross. If what you wanted was "the strongest opinion wins", that is a maximum, not a sum, and you will want a different approach. If what you wanted was "everything either mask touched at full strength", additive is precisely the union and you are in luck.

Inputs and outputs

masks in, mask out. No parameters, no widgets, nothing to tune - which is the appeal. The input is a plain MASK tensor (not a list), so this is the node for a batch of masks; if you are holding a Comfy list of masks - the other shape of "many" - this is not the tool, and a quick look with List / Batch Inspector will tell you which one you have before you wire it up.

The output is a batch-of-one [1, H, W] tensor, exactly the shape every mask consumer expects, so it drops into VAE Encode (for Inpainting), ImageCompositeMasked, a sampler's mask input, or a SEGS-building node with no conversion.

Install

Part of ComfyUI-Utility-Suite. ComfyUI Manager → search ComfyUI-Utility-Suite → install → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/tom-m-2020/ComfyUI-Utility-Suite

Restart ComfyUI. Nothing to download; the declared opencv-python-headless dependency belongs to other nodes in the pack, not this one. The suite is written against ComfyUI's newer V3 node API, so a current backend is required.

Traps

Empty batches error, they do not return empty. Zero masks in the tensor is a runtime error rather than a blank mask. If your upstream branch can legitimately produce nothing, guard it.

Rank matters in, rank does not matter out. A rank-2 mask in gives you a rank-3 [1, H, W] out - the same as a rank-3 batch of one. Downstream nodes are fine with that, but if you were doing shape arithmetic you should expect a leading dimension that was not there before.

Don't route a list into it. Feeding it a Comfy list of masks rather than a batch will fail on the type check rather than being helpful about it. The distinction between those two is the most common source of confusion in masking workflows generally, and this node is on the "batch" side of it.

There is no max or min mode here. One semantic, done predictably, is what you get. If you need different blend semantics inside a SEGS structure, the pack's mask-combining SEGS nodes do offer per-operation control - but those edit masks inside segments, not a standalone canvas mask.

CategoryUtility Suite/Mask

Inputs (1)

NameTypeDefaultDescription
masksMASK—

Outputs (1)

NameTypeDescription
maskMASK—