Nodes/ComfyUI-Rennart/🎨 Rennart Palette Extractor
ComfyUI Node

🎨 Rennart Palette Extractor

Steal the colors off any image, as prompt JSON

By Rennart2025·Created 16 days ago·Updated a day ago· 2
🎨 Rennart Palette Extractor
  • image
  • palette_json
  • palette_preview
  • color_count
num_colors8
min_delta_e10.0

You found a still frame, a painting, a screenshot, a photo of a room whose light you actually like. You want your generations in that palette instead of whatever the checkpoint decides. Rennart Palette Extractor takes the image, runs k-means over the pixels, and hands you the dominant colors as a hex list you can feed into a prompt - plus a swatch strip you can look at.

What it's actually for

Two very different jobs, and it's worth knowing which one you're doing.

The first is prompt-side palette control. Ideogram 4 was trained on structured JSON captions and is documented to read hex color palettes as conditioning, which is why the "same scene, different palettes" workflow exists at all. If you're building that kind of JSON prompt, this node produces exactly the fragment it wants, and the same tooling has already been ported to Krea.

The second job is deciding, and it's the honest one. Hex codes in a prompt do approximately nothing on a Flux or SDXL checkpoint - those models don't read "#3A6B8C" as an instruction. But five extracted swatches answer "what is this reference actually made of" in one glance, which tells you whether to reach for a color match, a palette quantize, or a different reference entirely.

How it works

Source-grounded, because the README doesn't tell you any of this. The node takes the first frame of the incoming IMAGE batch, converts it to PIL RGB, and resizes it to 150×150 - a global read of dominant color, not a detector.

Then sklearn.cluster.KMeans runs on the flattened pixels - n_init=4, random_state=42, so the result is deterministic: same image, same palette, every run. Clusters are sorted by population, so the most common color comes out first. Finally each centroid is converted to CIE LAB and compared against the colors already kept using CIE76 Delta-E; anything within min_delta_e of a survivor gets dropped.

That last step is the one people trip on: you can get fewer colors than you asked for, never more.

Inputs and outputs

  • image - the reference. IMAGE tensor, as any Load Image or VAE Decode gives you.
  • num_colors - 2 to 16, default 8. This is an upper bound: the k-means cluster count, capped again by how many unique colors exist after the 150×150 resize.
  • min_delta_e - 0 to 100 in 0.5 steps, default 10. The "is this a different color at all?" threshold in perceptual LAB distance. Raise it toward 15–25 for a flat, poster-like palette of clearly distinct colors; drop it to 0 if you want the near-duplicates. This is the knob that matters more than num_colors.
  • palette_json (STRING) - a key/value fragment, not a bare array: "color_palette": ["#RRGGBB", ...], dominant first, with no surrounding braces. That's deliberate - it's meant to be spliced into a larger prompt JSON object without anything having to strip or re-wrap it. Wire it into whatever builds your prompt text.
  • palette_preview (IMAGE) - a horizontal swatch strip, 100 px per color, with hex labels. Wire it to Preview Image or Save Image to see it.
  • color_count (INT) - how many colors survived dedup - the thing you check when the palette looks wrong.

Install

ComfyUI Manager → search ComfyUI-Rennart → install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/Rennart2025/ComfyUI-Rennart

Now the part the pack doesn't tell you. requirements.txt lists only torch and numpy, and pyproject.toml lists torch, pillow, numpy - but the extractor's helper imports sklearn.cluster.KMeans. scikit-learn is an undeclared dependency of this node. If it isn't already in your ComfyUI environment, run python -m pip install scikit-learn and restart ComfyUI.

Common issues

The node isn't in the node list at all. Check your startup console for [Rennart] ⚠️ .... The pack's __init__.py auto-imports every file and swallows failures with a printout, so a missing sklearn shows up as that warning and a missing node - not a crash. Other nodes in the pack, including Palette Preview, don't need it and load fine, which makes the absence look arbitrary.

Your six colors came back as three. Delta-E dedup doing its job on a low-contrast image. Lower min_delta_e, or accept that the image doesn't hold six separate colors.

One gray swatch, color_count 1. A runtime exception fell back to #808080 silently. It does not mean your image was gray. Check the console.

It keeps missing the accent color you care about. Expected - dominant-population sorting means a small red lamp loses to the wall every time. Crop to the region you care about first, or use a color-match node: the actual tool for "make my render's colors agree with this reference".

One thing to know about the pack: ComfyUI-Rennart is a small MIT collection by Rennart (Rinat Maksutov), and the extractor core is adapted from SurrealByDesign's Ideogram palette tools - related, not competitors. It gets essentially zero community discussion, so there's no reputation to lean on. For a node that returns either a hex list or a gray square, that's an acceptable risk level.

CategoryRennart/Color

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
num_colorsINT82–16
min_delta_eFLOAT10.00–100

Outputs (3)

NameTypeDescription
palette_jsonSTRING
palette_previewIMAGE
color_countINT