Nodes/Palette Director/Palette Composer
ComfyUI Node

Palette Composer

Click your palette colors instead of typing hex JSON by hand

By SKBv0·Created 3 months ago·Updated 2 months ago· 10
Palette Composer
    • palette_hex
    • role_hex
    • weights
    • palette_report
    palette_state{"colors":[{"hex":"#111111","weight":0.34,"role":"bg"},{"hex":"#2B2B2B","weight":0.24,"role":"main"},{"hex":"#EDEDED","weight":0.18,"role":"human"},{"hex":"#FF3158","weight":0.14,"role":"material"},{"hex":"#13D8C8","weight":0.1,"role":"accent"}]}

    Palette Composer is the friendly front end of the Palette Director pack. Its sibling node does all the real work; this one just exists so you can pick colors with a color picker and drag weight sliders instead of typing #FF3158 0.14 material into a text box. If you've ever pasted a hex string wrong and spent twenty minutes wondering why your renders came out brown, you already know why this node exists.

    It's a thin node, honestly. Its only input is a JSON blob called palette_state, and its four outputs are just strings. The magic is that the pack ships a small web extension that replaces that JSON with an actual editor: five color swatches for the fixed roles bg, main, human, material, accent, a native color picker per swatch, a hex text field, and a weight slider that shows the running percentage. You can also set a role per color from a dropdown. The whole thing serializes your edits back into that JSON widget for you.

    How it works

    Under the hood it's a strict serializer with a forgiving parser. Your edits land in palette_state as JSON - a list of {hex, weight, role} objects. The node reads it, normalizes the weights so they sum to 1, and emits four strings:

    • palette_hex - your colors, space-separated
    • role_hex - one hex per role in fixed order (bg, main, human, material, accent)
    • weights - the normalized weights, space-separated
    • palette_report - a human-readable summary so you can sanity-check what you actually made

    Those first three are what you wire forward into the Palette Director node's optional inputs: palette_hex_input, role_hex_input, and weights_input. That's the whole pipeline - Composer formats, Director consumes.

    The tolerance is the one genuinely clever bit. If you hand-edit the JSON and break it - bad hex, non-numeric weight, malformed braces - the parser falls back to defaults instead of hard-failing, so a corrupted or ancient workflow still opens. The README is explicit that this is deliberate. The flip side: if something looks wrong, the node won't tell you. Check palette_report or look at the rendered strips to see what actually made it through.

    Install

    Same as the rest of the pack, since Composer ships inside it:

    cd ComfyUI/custom_nodes
    git clone https://github.com/SKBv0/ComfyUI_PaletteDirector
    

    Restart ComfyUI. Dependencies are just numpy, pillow, and torch - all already present in a stock install, so there's nothing extra to download. No API keys, no model files. If the editor doesn't show up after a restart, hard-refresh your browser tab; the extension is plain JavaScript and your cache will cheerfully serve you the old page.

    Gotchas

    • The role list is fixed at five. There's no way to have six colors or an eighth role - the whole pack (and the LoRA it works with) is built around exactly bg main human material accent.
    • Fewer than four colors in the state get padded with defaults, so an empty editor still produces output. That's handy, but it means "I cleared it" isn't a clean blank state.
    • This node doesn't touch your image at all. It's a color-capture tool, not a grade - all it ever outputs is text.

    Want the short version? It's the color picker you click before Palette Director does the thinking. If you'd rather type hex strings directly, you can skip this node entirely and feed the Director's manual fields by hand - that's the entire point of its design.

    CategoryPalette Director

    Inputs (1)

    NameTypeDefaultDescription
    palette_stateSTRING{"colors":[{"hex":"#111111","weight":0.34,"role":"bg"},{"hex":"#2B2B2B","weight":0.24,"role":"main"},{"hex":"#EDEDED","weight":0.18,"role":"human"},{"hex":"#FF3158","weight":0.14,"role":"material"},{"hex":"#13D8C8","weight":0.1,"role":"accent"}]}

    Outputs (4)

    NameTypeDescription
    palette_hexSTRING
    role_hexSTRING
    weightsSTRING
    palette_reportSTRING