ComfyUI Node

CS Mask Grow

The mask grow that doesn't turn circles into diamonds

By chflame163·Created 11 days ago·Updated a day ago· 49
CS Mask Grow
  • mask
  • MASK
grow0
preserve_soft_edgesfalse

Growing or shrinking a mask is the most boring operation in every workflow, and the stock Grow Mask node is exactly as good as you'd expect something that boring to be. CS Mask Grow is the upgrade: it does the same job with an exact Euclidean disk, runs a lot faster on big frame batches, and doesn't turn round contours into jagged diamonds when you push the value high.

That diamond thing is the real reason this node exists. A naive grow repeatedly dilates the mask one pixel at a time, and repeated dilation along the two axes favors diagonal growth - Manhattan-distance-style contours that look squared off. The stock node gets blocky at big radii, and on a video frame batch it's also slow, because it's doing that pass per frame. CS Mask Grow instead computes an exact discrete Euclidean disk: every pixel's grown value is based on true distance from the original edge, so a circle stays a circle at any radius.

How it actually works

The implementation is worth knowing because it explains the speed claim. For the default binary path it builds a prefix sum (integral image) of the mask, then for each row offset in the disk it does a constant-time range query to test whether the disk covers a filled pixel. That's the whole grow done in a handful of passes over the width, not one pass per radius pixel. The soft-edge path does grayscale dilation with the same disk using row-wise max pooling, which keeps your alpha transitions intact instead of throwing them away.

It's also built for video. The node estimates memory per frame, batches as many frames onto the GPU as fit (up to 64, targeting ~70% of free VRAM), halves the batch if it hits an OOM, and falls back to CPU one frame at a time if even that fails. You don't set any of this - it just handles a 200-frame batch without you thinking about it.

The inputs you set

Three inputs, and two of them matter:

  • mask - a standard MASK, single image or a whole video batch.
  • grow - pixels, from −4096 to 4096. Positive expands outward, negative shrinks inward, 0 changes nothing. Negative values invert the disk trick internally, so shrink is just as clean as grow.
  • preserve_soft_edges - the toggle that changes behavior. Off (default): the mask is binarized at gray value 128 and you get a hard 0/1 mask out. On: the grayscale alpha transitions survive, which is what you want when feathering before a composite.

Output is a standard MASK with the same frame count and dimensions you put in.

When you'd reach for it

Same places you use any grow/shrink: pull a mask in tight before inpainting so the model doesn't repaint your subject's edges, expand a subject mask for outpainting or background cleanup, or feather the hard edge before a blur pass. The differentiator is video - if your mask comes from a per-frame segmentation pass and you need to clean it up across a clip, this is the node that stays fast and keeps shapes honest.

Install is the pack-level drill: ComfyUI Manager, search "ComfyUI_CineStyle", or cd ComfyUI/custom_nodes && git clone https://github.com/chflame163/ComfyUI_CineStyle, then restart. Look for it under 😺dzNodes/CineStyle. Like the rest of the pack it's built on ComfyUI's newer node API, so update ComfyUI if the nodes don't appear after install. No model downloads, no extra dependencies beyond what the pack already installs - just clean torch math. One honest note: it's a brand-new pack, so the docs are thin and the community trail is basically nonexistent yet. The node itself is simple enough that you'll figure it out in one run.

Category😺dzNodes/CineStyle

Inputs (3)

NameTypeDefaultDescription
maskMASKStandard ComfyUI MASK tensor; video frames are processed as a batch.
growINT0-4096–4096Positive values grow outward; negative values shrink inward, in pixels.
preserve_soft_edgesBOOLEANfalseKeep grayscale alpha transitions. When disabled, input is binarized at gray value 128 before processing.

Outputs (1)

NameTypeDescription
MASKMASK