Nodes/ComfyUI_ContrastingColor/Contrasting Complementary Color
ComfyUI Node

Contrasting Complementary Color

This node picks a readable overlay color for you

By dasilva333·Created 2 years ago·Updated 2 years ago· 1
Contrasting Complementary Color
    • STRING
    r14
    g21
    b19
    threshold0.50
    dark_value0.20
    bright_value0.85
    saturation0.90

    You've got a dark navy generated background, and you want to stamp a watermark or a caption on it. What color? White will sit fine on the navy... until the image also has a bright sky. This node is the "just compute it" answer to that whole class of problem: give it an RGB color, and it hands you back a contrasting complementary hex code that stays readable whether the background runs dark or light.

    It's a tiny pure-Python utility from the utils category in the ComfyUI_ContrastingColor pack. There's no model, no API key, no dependencies - requirements.txt is literally empty. That's the whole appeal: it's the color-picker equivalent of a reroute node, nothing to break.

    How it actually works

    The mechanism is three steps, and it's all in contrasting_color.py:

    1. Compute relative luminance of your input color using the standard Rec.709 formula (0.2126 R + 0.7152 G + 0.0722 B after linearizing each channel). That's the same math browsers use, so it's legitimately "industry standard."
    2. Shift the hue by 180°. It converts RGB to HSV, adds 0.5 to the hue, and converts back - that's the definition of a complementary color, hue-wise.
    3. Flip the brightness to match. If the background's luminance is below the threshold, you get a bright color; above it, a dark one. Saturation gets forced to whatever you set.

    The result comes back as a single STRING output formatted #RRGGBB (uppercase hex, ready to paste anywhere).

    The inputs that matter

    Seven inputs, and you'll actually touch maybe three of them.

    • r / g / b - your background color as three 0–255 integers. Defaults are 14, 21, 19, a near-black blue-green, so you'll almost always change these. Slightly awkward: there's no hex input field, so if you're working from #1F2A35 you'll be doing a quick mental conversion (or just read the two hex digits per channel).
    • threshold (default 0.5) - the luminance line between "treat this as dark" and "treat this as light."
    • dark_value / bright_value (defaults 0.2 / 0.85) - the HSV value applied on the light and dark branches respectively. These are your fine-tune knobs.
    • saturation (default 0.9) - how vivid the output color is. Drop it toward 0.4 if you want a muted, quieter accent.

    Worth knowing: the class name ends in |pysssss, which is just this author's naming convention - it has nothing to do with pythongosssss or their nodes. Don't go hunting in that pack for it. The display name is "Contrasting Complementary Color."

    What you wire it into

    ComfyUI core doesn't draw text natively, so your hex string is destined for an overlay or compositing node - the WAS Node Suite text overlay and image-compositing nodes are the usual suspects (per the ecosystem rundown, that's WAS's whole job), and most of those accept a hex color string. The node is marked as an output node, so it also plays nice as a terminal in workflows that otherwise have nothing to "complete."

    Where this shines is dynamic setups: when the background color is itself computed mid-graph (say, sampled from your generated image), the text color can't be hardcoded - and this node keeps it self-consistent.

    Installing it

    ComfyUI Manager, search "ComfyUI_ContrastingColor" (or the display name), install, restart. Or the manual route:

    cd ComfyUI/custom_nodes
    git clone https://github.com/dasilva333/ComfyUI_ContrastingColor
    

    Then restart ComfyUI. No model files, no pip installs - the pack ships zero dependencies, so there's nothing else to fetch.

    The honest caveats

    The one thing to keep in mind: this picks a complementary hue with flipped brightness, not a guaranteed-WCAG-AA color. A single luminance threshold is a good heuristic, but mid-tone backgrounds can still land you a color that fails a real contrast-ratio check (the actual WCAG math is a ratio, not a cutoff). If readability is mission-critical, sanity-check the output against a contrast checker. For everything else - captions, watermarks, UI accents, chart labels - it's a genuinely nice little node that takes a whole category of guesswork out of your workflow.

    Categoryutils

    Inputs (7)

    NameTypeDefaultDescription
    rINT140–255
    gINT210–255
    bINT190–255
    thresholdFLOAT0.500–1
    dark_valueFLOAT0.200–1
    bright_valueFLOAT0.850–1
    saturationFLOAT0.900–1

    Outputs (1)

    NameTypeDescription
    STRINGSTRING