Nodes/ComfyUI_EmAySee_CustomNodes/EmAySee Mask Universal XY
ComfyUI Node

EmAySee Mask Universal XY

Expand, shrink, and punch holes in one node

By EmAySee·Created about a year ago·Updated 4 months ago· 2
EmAySee Mask Universal XY
  • mask
  • MASK
expand_x0
expand_y0
hole_width0
hole_height0

EmAySee Mask Universal XY is the one mask-shaping node you'll actually reach for. It combines two operations from this pack into a single pass: you can expand or shrink a mask independently on the X and Y axes and punch a rectangular hole out of its center, all in one node. That's the entire toolbox most masked-inpainting prep needs, minus the wire spaghetti of chaining three separate nodes.

The workflow that wants this is the classic detailer/inpaint-prep cycle. You've got a mask that hugs a subject too tightly - you want to expand it by a few pixels so the sampler has room to blend edges and doesn't leave a hard seam. Or the mask overshoots and you want to pull it in. Or you're doing a "keep the center, redraw the outline" pass and need to hollow the mask out. Universal XY does all three, and you can combine them in one execution: expand the edges 24px and punch a hole down the middle in the same step.

How it works

The expand/shrink half is real morphological dilation and erosion done with max pooling, applied per-axis. Expand positive values grow the mask outward using a max-pool kernel sized to your pixel amount; negative values erode it (it max-pools the inverted mask, then inverts back, which is the standard trick for erosion). The hole half is simpler: it finds the center of the mask's white region and zeroes out a rectangle of your chosen width and height there.

The two operations are independent and both are optional - set expand_x and expand_y to 0 and skip the hole by leaving hole_width/hole_height at 0, and it returns your mask untouched.

The inputs that matter

Five inputs, and the naming is honest:

  • mask - the MASK you're reshaping.
  • expand_x / expand_y - integers from −1024 to 1024, default 0. Positive grows, negative shrinks, per axis. In pixels, not percent.
  • hole_width / hole_height - integers from 0 to 8192, default 0. Zero means no hole. The hole is centered on the mask's content, not the canvas - the node computes the centroid of the white pixels and punches there, which is what you want for a centered subject.

The single output is the reshaped MASK. It feeds straight into a masked sampler, a MaskUnion to combine with other regions, or EmAySee_MaskOverlay when you want to eyeball the result first.

Installing it

Part of the EmAySee pack, installed like any custom node collection:

# ComfyUI Manager: search "ComfyUI_EmAySee_CustomNodes" and install
# or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/EmAySee/ComfyUI_EmAySee_CustomNodes

Restart ComfyUI afterward. The pack ships no requirements.txt; this node only needs torch, so install is clean apart from the pack's loud startup banner.

Common issues

Two things trip people up. First, expansion and erosion here are axis-aligned rectangles in effect - a heavily concave mask gets its edges grown, but the shape's interior details don't expand "with" the boundary the way a true distance-transform would. For most detailer work that's fine. Second, the hole is always centered on the content's centroid, not on where you think the middle is - if your subject is off-center, so is the hole, and there's no offset parameter to fix it. Work around it by reshaping the input mask first or accepting the centered hole. Also worth knowing: this node and EmAySee_MaskExpandShrinkXY share the same expand/shrink code, so if you only ever expand or shrink, either one works - Universal XY is the one to use when you want the hole too.

CategoryEmAySee/Mask

Inputs (5)

NameTypeDefaultDescription
maskMASK
expand_xINT0-1024–1024
expand_yINT0-1024–1024
hole_widthINT00–8192
hole_heightINT00–8192

Outputs (1)

NameTypeDescription
MASKMASK