Nodes/ComfyUI_Swwan/Mask Combine (Swwan)
ComfyUI Node

Mask Combine (Swwan)

Add, subtract, intersect — then crop to the region that's left

By aining2022·Created 10 months ago·Updated about 18 hours ago· 33
Mask Combine (Swwan)
  • mask_1
  • mask_2
  • mask
  • width
  • height
◄operation▾►
◄bbox_mode▾►
◄alignment▾►

What it's for

Two masks, one output, and a choice of what "combining" means. If you've done any localised editing, you already do this by hand: keep the subject's mask but cut the eyes out of it, union two segmented parts, intersect a depth mask with a segmentation mask to get only the near bits.

Mask Combine does that arithmetic in one node, and then does the second thing you always end up needing afterwards - crops the canvas down to the region the result actually occupies, optionally squared off to 1:1.

It comes from Goohaitools, and it's the reason those Chinese labels are on the widgets: 相加, 相减, 相交, 排除, the four 取 (take) modes, 关闭 and the alignment options.

The operations, honestly described

Eight of them, plus a crop stage that runs afterwards:

  • 相加 adds and clamps - a union that keeps soft edges.
  • 相减 subtracts the second mask from the first with a clamp(1 - min(...))-style form, so overlapping areas are cut out and non-overlapping areas are untouched.
  • 相交 is the minimum: only pixels lit in both.
  • 排除 is the inverse of the union - everything that is neither mask. That one surprises people; it's an exclusive-or-shaped operation and the result is usually the whole canvas minus your subjects.
  • 水平取左 / 水平取右 / 垂直取上 / 垂直取下 work on bounding boxes rather than pixels: they take whichever mask's region sits on that side and hand it back. These are for "keep the left character, drop the right one" without painting anything.

Several of these short-circuit: if an operation produces a completely empty result, the node returns a zeros mask with width=0, height=0 instead of a cropped region. And if both inputs are unconnected, you get torch.zeros((1, 1024, 1024)) with 0,0 - a fixed-size black canvas that has nothing to do with your actual image dimensions. Somebody will wire this wrong once and spend an hour wondering why the mask is 1024×1024.

Both masks must be the same height and width or the node raises 两个遮罩尺寸必须相同. If only one is connected, the other is assumed to be all zeros, which makes the operation a no-op on the real mask - occasionally handy as a conditional bypass.

The crop stage

bbox_mode runs after the arithmetic: 关闭 leaves the full canvas, 原始比例 crops to the natural bounding box of the result, and the four 1:1 modes crop to a square built from that box - 长边不变 keeps the longest side (widening the short one), 短边不变 keeps the shortest, 宽度不变 and 高度不变 anchor to that axis. alignment then decides which way the square hangs off the original box: left, right, centre, top or bottom.

The payoff is the width and height outputs. Note the node's own description: these are the effective region, not necessarily your canvas size - so if bbox_mode is on, they're the crop you just performed, and they're exactly what you feed into a crop node and then back into an uncrop node. If bbox_mode is 关闭, they're the canvas.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/aining2022/ComfyUI_Swwan
cd ComfyUI_Swwan
python -m pip install -r requirements.txt

Restart, hard-refresh, search Swwan. Pure tensor maths - no OpenCV, no scipy, no model, no GPU requirement. The mask tools live under Swwan/Advanced/Mask alongside Mask Process, Mask Analyze and Mask Segments.

Common issues

两个遮罩尺寸必须相同. Resize one of them first. Unioning masks from different crop stages is the usual way this happens.

1024×1024 black output. Both inputs are disconnected - the fallback canvas. Connect at least one.

The result is the whole frame. You probably wanted 排除 or an intersected pair; also check bbox_mode isn't off when you were expecting a crop.

Everything after this node is misaligned. You turned on a 1:1 bbox mode and the crop no longer matches where the mask was on the original canvas. Carry the width/height outputs downstream, and remember BOX, BBOX and this region pair are different protocols - they don't interchange.

CategorySwwan/Advanced/Mask

Inputs (5)

NameTypeDefaultDescription
operationCOMBO8 options: 相加, 相减, 相交, 排除, 水平取左, 水平取右, +2
bbox_modeCOMBO6 options: 关闭, 原始比例, 1:1长边不变, 1:1短边不变, 1:1宽度不变, 1:1高度不变
alignmentCOMBO5 options: 左对齐, 右对齐, 居中, 上对齐, 下对齐
mask_1optMASK—
mask_2optMASK—

Outputs (3)

NameTypeDescription
maskMASK—
widthINT—
heightINT—