ColorshiftColor
Turn any image into a numbered color palette you can actually recolor
- images
- lock_masks
- palette_override
- images
- palette
- index_maps
- palette_preview
ColorshiftColor is a KMeans color-quantization node: it crushes an image down to a fixed number of flat colors, then hands you the palette, a per-pixel index map, and a numbered preview so the rest of the pack can recolor by swatch number. It's the entry point of the ComfyUI-ColorshiftColor pack (alongside CsCPaletteEditor and CsCFill), and it's built for one specific job: flat-color cel/anime art that you want to re-theme or batch-recolor without repainting a single region.
If your images are photographs, this is the wrong tool - KMeans on a photo just gives you posterized mush. Feed it clean flat art and it's the difference between "recolor by hand in Krita" and "type a number, hit run."
How it works
The node clusters pixels in RGB space with scikit-learn's KMeans, then assigns every pixel to its nearest cluster center. Two details keep it fast and predictable:
- It downsamples the image 0.5x and clusters only a
sampling_rateslice (default 0.25) of those pixels, so it's cheap even on full video frame batches. That's the whole point of thesampling_rateslider - lower it on big images for speed, nudge it up if the palette comes out wrong. - After clustering it re-sorts the palette by screen area, so the biggest color region is index 0, then 1, 2... That ordering matters: every other node in the pack references swatches by number.
KMeans itself uses a fixed random state, so palette geometry is reproducible for a given image; the pixel sampling isn't seeded, so expect tiny run-to-run wobble. Irrelevant for recolor work.
The inputs that matter
Two dials you'll actually touch, and a pile of options:
images- any IMAGE, stills or a batch of video frames.color_count(2–64, default 8) - how many flat colors to reduce to. This is the parameter. Too few and adjacent colors merge; too many and it stops being "flat."
The rest are set-and-forget: sampling_rate (speed/accuracy), n_init (KMeans restarts, leave at 3), font_size (size of the numbers on the preview). palette_override lets you force your own palette instead of computing one - the node just matches every pixel to the nearest color in yours. lock_masks keeps the regions you mask out of the quantization untouched.
What comes out
images- the quantized, flat-color image.palette- the N colors as a PALETTE tensor.index_maps- the sneaky one. It's typed MASK, but it does not carry 0–1 alpha values: it's an integer label per pixel (0 tocolor_count−1) saying which swatch that pixel belongs to. Don't feed it into normal mask math expecting floats.palette_preview- the numbered swatch grid, ready to eyeball or save. Those numbers are whatlock_color_numand the operations strings in the sibling nodes reference.
Install
No model files, no API keys, nothing to download - just one Python dependency, which the README flags in its very first line:
cd ComfyUI/custom_nodes
git clone https://github.com/852wa/ComfyUI-ColorshiftColor
pip install scikit-learn
Or skip the shell: search "ComfyUI-ColorshiftColor" in ComfyUI Manager and hit install. Restart ComfyUI after. scikit-learn is the only non-trivial dependency (it's the KMeans engine) and it's pure CPU, so it installs in seconds.
Issues worth knowing
- The README is Japanese. The gist that matters: for single-color-background video, don't render with Video Combine - the README says the encoder adds noise, and recommends saving numbered PNGs with SaveImage instead. The example workflows use VideoHelperSuite to load video and feed frames through this node in a batch.
- It will happily quantize a photo, and the result will look like a 1998 web-safe color scheme. Match the tool to the flat art, and it's genuinely great.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| color_count | INT | 82–64 | — |
| lock_masksopt | MASK | — | |
| palette_overrideopt | PALETTE | — | |
| font_sizeopt | INT | 2010–50 | — |
| sampling_rateopt | FLOAT | 0.250.01–0.5 | — |
| n_initopt | INT | 31–10 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| palette | PALETTE | — |
| index_maps | MASK | — |
| palette_preview | IMAGE | — |