ComfyUI Node

Mask Stroke

Outlines and sticker borders, straight from a mask

By 1hew·Created about a year ago·Updated 7 days ago· 33
Mask Stroke
  • mask
  • mask
fill_holefalse
stroke_width20.00
include_masktrue

Sometimes what you want isn't the mask itself - it's the border around the mask. A white outline around a cutout for a sticker-style composition, a clean ring around a subject for a vignette, a stroke that marks a region boundary for inspection. Mask Stroke takes a mask and produces exactly that: a stroke mask around the foreground, at whatever thickness you ask for.

How it works

The classic dilate-and-subtract trick, done with OpenCV. The mask is converted to a uint8 image, dilated with an elliptical structuring element sized by stroke_width, and the original is subtracted from the dilation. What's left is a ring - the stroke - hugging the mask's edge. The elliptical kernel matters: it gives you smooth, rounded outlines instead of blocky corners.

Two quality-of-life features are worth knowing. fill_hole runs an optional hole-fill first, so a mask with a donut-hole inside gets stroked around the outer edge only, not also around the inner hole. And there's a nice piece of input ergonomics: stroke_width below 1.0 is treated as a fraction of the mask's smaller dimension. So 0.05 means "5% of the short side," which keeps outlines proportional whether you're working at 512 or 2048. Values of 1.0 and up are raw pixels.

The inputs that matter

  • mask (MASK) - the foreground whose outline you want.
  • stroke_width (FLOAT, default 20) - thickness. Sub-1.0 = percentage of the short side; otherwise pixels. The one you'll fiddle with.
  • include_mask (BOOLEAN, default on) - union the original mask into the output. Off means you get only the ring, which is what you want if the output is going to be combined with something else.
  • fill_hole (BOOLEAN, default off) - as above.

One output: mask (MASK), the stroke (or stroke + original) mask. It's batch-aware, so a stack of masks gets a stack of strokes, processed in parallel.

Installing it

ComfyUI Manager → search ComfyUI-1hewNodes → install → restart. Manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/1hew/ComfyUI-1hewNodes

Restart ComfyUI. No model downloads; this node is OpenCV + numpy, both in the pack requirements (which also pulls rembg/ultralytics and friends whether you need them or not). The pack wants a current ComfyUI - it uses the newer comfy_api.latest API - so update ComfyUI if the nodes don't show.

Common issues

The classic mistake is stroke_width in the 0–1 range when you meant pixels: you'll type 0.5 meaning half a pixel and instead get a 50%-of-short-side border. If your outline is unexpectedly enormous, that's the fraction mode biting. With include_mask off, a fully-transparent foreground yields an empty output - stroke only exists where there's mask to dilate. And for very thin strokes on big images, bump the mask resolution first, because a 1px ring on a 4K image can look aliased.

Category1hewNodes/mask

Inputs (4)

NameTypeDefaultDescription
maskMASK
fill_holeBOOLEANfalse
stroke_widthFLOAT20.000–8192
include_maskBOOLEANtrue

Outputs (1)

NameTypeDescription
maskMASK