Nodes/ComfyUI-HairOverlay/Hair Edge Color Overlay
ComfyUI Node

Hair Edge Color Overlay

Want a different hair color without re-rolling? This node dyes it for you.

By mingyu4537-creator·Created 5 months ago·Updated 5 months ago· 0
Hair Edge Color Overlay
  • image
  • hair_mask
  • face_mask
  • image
  • overlay_mask
overlay_r255
overlay_g50
overlay_b60
dark_threshold120
face_range0.60
color_intensity0.25
smoothness30
falloff2.5
face_detect

You just generated a portrait you love, and the only thing wrong with it is the hair color. Your first instinct is to change the prompt and re-roll - which changes the pose, the lighting, and half the face too. Hair Edge Color Overlay (class HairEdgeOverlay, from the ComfyUI-HairOverlay pack) is the cheap deterministic alternative: it tints the hair that's already there, airbrush-style, strongest near the face and fading out toward the back of the head. No re-sampling, no seed roulette.

It's a pure post-process node - image in, image out - so it lives after your VAE decode and before Save Image. It's the "preview the dye job" tool: crank in a color, see if pink hair works on this character, then either keep it or re-roll with a changed prompt. For a real recolor you'd still rather inpaint, but for previewing shades this is instant and free.

How it works

The mechanism is three layers multiplied together, which the source makes easy to follow:

  1. A hair mask. If you feed the optional hair_mask, it uses that (and resizes it to your image if needed). Otherwise it auto-detects hair by brightness: pixels with HSV value below dark_threshold and low saturation count as hair, then it runs morphological fill and a Gaussian blur scaled by smoothness to get a soft mask.
  2. A face-proximity gradient. This is the whole trick. It finds the face - either from an optional face_mask, or by detecting it - then builds a falloff that's 1.0 right at the face and decays toward zero with falloff controlling the curve. That's why the color is bold at the hairline and gone by the back of the head.
  3. The final mask is hair × face-proximity, blurred again, then clamped so color never bleeds past the hair. The color is just added on top: result = image + overlay_color × mask × color_intensity.

The output overlay_mask is that exact final mask, which is handy if you want to see what it "decided" was hair - or composite the color yourself.

The inputs that matter

Most of the sliders are set-and-forget, but three are worth touching:

  • overlay_r / overlay_g / overlay_b - the RGB color, defaulting to a warm pink-red (255/50/60). This is the whole point of the node.
  • color_intensity - how strongly the color applies (default 0.25).
  • dark_threshold - the hair-brightness cutoff for auto hair detection. Default 120 works for dark hair; bright/blonde hair will need it raised or the node simply won't see your hair.

face_range widens how far from the face the effect reaches, falloff sharpens the fade, smoothness is the airbrush softness, and face_detect picks between auto_skin (HSV skin detection) and center_bias (assumes the face sits top-center). Both optional mask inputs, hair_mask and face_mask, are the fast path to accurate results.

Install

It's a one-file node with no dependencies beyond what ComfyUI already ships (torch, numpy, PIL - there's no requirements.txt). Easiest via Manager: search ComfyUI-HairOverlay, install, restart. Or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/mingyu4537-creator/ComfyUI-HairOverlay.git

Then restart ComfyUI. The node shows up under image/color as "Hair Edge Color Overlay". It also handles batches, so it runs per-frame on an animated or multi-image batch without extra work.

Where it trips you up

The auto face detection is genuinely crude - no face model, just skin-color statistics. On non-skin tones, busy backgrounds, or faces shot from the side, auto_skin can guess wrong and the overlay lands on the forehead instead of the hair. center_bias just assumes the face is top-center, which is fine for a centered portrait and useless otherwise. If the effect keeps landing wrong, stop fighting the knobs and wire in a face_mask from a segmentation/face-detect node - the whole node is far more predictable when you give it masks.

Also remember what this is: it's tinting pixels, not re-rendering. The result will always look a bit like a dye job laid over the original. That's the point for previewing, but if you need the color to actually re-light the scene, inpaint instead. For everything else, this is a surprisingly handy little node to keep one click away.

Categoryimage/color

Inputs (12)

NameTypeDefaultDescription
imageIMAGE
overlay_rINT2550–255
overlay_gINT500–255
overlay_bINT600–255
dark_thresholdINT12010–250
face_rangeFLOAT0.600.1–3
color_intensityFLOAT0.250.05–1
smoothnessINT305–100
falloffFLOAT2.51–5
face_detectCOMBO2 options: auto_skin, center_bias
hair_maskoptMASK
face_maskoptMASK

Outputs (2)

NameTypeDescription
imageIMAGE
overlay_maskMASK