Nodes/ComfyUI-JNK-Tiny-Nodes/Stroke RGBA Image JNK
ComfyUI Node

Stroke RGBA Image JNK

Outline anything with a stroke ring, alpha intact

By AljnkΒ·Created about a year agoΒ·Updated 12 months agoΒ· 3
Stroke RGBA Image JNK
  • background_image
  • layer_image
  • layer_mask
  • image
β—„invert_masktrueβ–Ί
β—„stroke_grow0β–Ί
β—„stroke_width8β–Ί
β—„blur0β–Ί
β—„stroke_color#000000β–Ί

Every compositor eventually needs the same thing: a clean outline around a subject, the kind of stroke you see in stickers, profile icons, and character art. "Stroke RGBA Image JNK" adds that ring to a layer and composites it onto a background in one pass - and it preserves the alpha channel while it does it, which is rarer in ComfyUI image nodes than you'd think. If you're building layered composites (the pack pairs it with its Create RGBA Image and Add Layer Overlay nodes), this is the missing outline step.

The mechanism is the interesting part, because it's real image-processing, not a paint call. You feed it a background_image and a layer_image. The layer's alpha channel becomes the mask that defines the shape. The node then builds the stroke as a ring: it expands the mask outward by inner_stroke = stroke_grow - stroke_width/2, expands it again by the full stroke_width more to get an outer boundary, and subtracts the inner from the outer. What's left is a donut-shaped mask exactly one stroke_width thick, hugging the silhouette. That ring gets filled with stroke_color and pasted onto the background behind the layer, so the layer sits on top of its own outline. The blur input (0–100) softens the edges of the ring, which is how you get that feathered, glow-adjacent look instead of a razor edge.

stroke_grow is the dial you'll actually fiddle with. It's an offset applied to the whole stroke: positive values push the ring outward away from the shape (a halo), negative values tuck it inside the silhouette. With stroke_grow at 0 and stroke_width at 8, the stroke is centered on the silhouette edge - 4 pixels out, 4 in. Bump stroke_grow up and you get a true outline sitting entirely outside the subject; that's the setting for the classic sticker look.

One behavior that bites people: the invert_mask toggle only applies when you pass an optional layer_mask. When the node derives the mask from the layer's own alpha channel, invert_mask is ignored - which is correct, because inverting the alpha would outline the transparent parts. If your layer has no alpha and you don't supply a mask, the node bails out with a ---JNK---> StrokeImage_JNK console message and returns the background unchanged. So: RGBA layers just work, RGB layers need you to bring a layer_mask.

The inputs that matter:

  • stroke_width - how thick the ring is (default 8).
  • stroke_grow - push the ring outward (positive) or inward (negative).
  • stroke_color - a hex string like #000000 or #ff0000.
  • blur - feather the stroke edges, 0 for a hard edge.
  • invert_mask - only relevant when you supply a layer_mask.

Output is a single image, the composited result.

Install: ComfyUI Manager β†’ search "JNK" β†’ Install, then restart. Or:

cd ComfyUI/custom_nodes/
git clone https://github.com/Aljnk/ComfyUI-JNK-Tiny-Nodes.git

Then restart. The heavy lifting uses scipy and Pillow, which ComfyUI already has in its environment - no extra pip installs for this node.

Gotchas: it operates per-frame on batches, so a video batch works but each frame gets its own stroke - fine for static overlays, a shimmer risk on animation. Mask size mismatches silently fall back to a solid white mask with a console warning, so check the log if your stroke looks like it outlined the whole frame. And the color is a hex string with the # - the node doesn't validate it, so a typo gives you a black or default-looking outline. For a first run, keep it simple: RGBA layer, stroke_width 8, stroke_grow 0, and dial from there.

CategoryπŸ”§ JNK

Inputs (8)

NameTypeDefaultDescription
background_imageIMAGEβ€”
layer_imageIMAGEβ€”
invert_maskBOOLEANtrueβ€”
stroke_growINT0-999–999β€”
stroke_widthINT80–999β€”
blurINT00–100β€”
stroke_colorSTRING#000000β€”
layer_maskoptMASKβ€”

Outputs (1)

NameTypeDescription
imageIMAGEβ€”