Image to LUT (Cube)
Turn Any Image Into a .cube LUT (and Why It Looks Posterized)
- image
- lut_filepath
You've got a reference image with a color mood you love and you want that mood on your generations, but you can't be bothered to hand-tune curves every time. That's the job Image to LUT (Cube) reaches for: it sucks the dominant colors out of any image and writes them to a standard .cube LUT file you can reuse anywhere. It's a tiny node from a tiny pack (the ComfyUI-LUT repo is a single commit), so set expectations now - this is a palette-extraction utility, not a pro color-grading tool. But for "give me that teal-and-orange look" it does exactly one thing and does it without calling any API or needing a key.
What it actually does
Load an image, set two numbers, hit run, and a generated_lut.cube lands in your ComfyUI/output folder. The mechanism, from the source: the image is flattened into raw pixels and fed to a K-Means clustering with num_colors clusters, so you get back a palette of the image's most representative colors. Those palette colors are then cycled through to fill every entry of a 3D cube - a LUT_3D_SIZE grid - and the whole thing is written out as a standard Adobe .cube file.
One honest caveat before you get excited: this LUT doesn't do smooth interpolation between palette colors. Each cube position just maps to whichever palette color its index lands on. Applying it gives a posterized, quantized look - think "Instagram filter after too many adjustments," not a buttery film grade. That's fine if that's the aesthetic you're after (retro/duotone vibes) and exactly the wrong tool if you wanted a subtle grade. There's also a harmless quirk in the code: a pointless RGB→BGR→RGB double conversion that cancels itself out. Classic pastebin-era code.
The inputs and output that matter
Three inputs, and a beginner really touches two of them:
- image - your reference image. Feed it the output of a
LoadImage. Note it only reads the first frame of a batch; the rest are ignored. - num_colors - how many dominant colors K-Means extracts (default 17, range 1–256). Lower = more aggressive posterization.
- lut_size - the cube resolution, i.e. the
LUT_3D_SIZEwritten to the file (default 17, range 2–64). 17 gives a 17×17×17 = 4,913-entry LUT, plenty for this use.
The single output, lut_filepath, is a STRING - the absolute path to the saved .cube file. That's it. Wire it into a ShowText node to eyeball the path (that's literally what the pack's example workflow does), then take the file into whatever applies LUTs: DaVinci Resolve, Photoshop, or a LUT-handling node if you've got one.
Installing it
Two ways, same result:
# ComfyUI Manager: search "ComfyUI-LUT" and hit install, then restart ComfyUI.
# Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/thezveroboy/ComfyUI-lut.git
# then, because there is no requirements.txt:
/path/to/your/venv/bin/pip install opencv-python scikit-learn
No model files to download - it's pure CPU math on your image, so it runs on anything.
Where people get burned
The big one is silent: the pack ships no requirements.txt, yet nodes.py imports cv2 and sklearn at load time. ComfyUI's base install has neither, so if you just clone it, the node fails to load with a ModuleNotFoundError: No module named 'sklearn'. Manager won't fix it either, because Manager installs what a requirements.txt lists - and there isn't one. Install opencv-python and scikit-learn into the same Python environment ComfyUI runs from, then restart.
Second gotcha: the output filename is hardcoded to generated_lut.cube, so every run overwrites the last one. Found a palette you like? Rename or copy the file before the next run, or it's gone.
Third: the output is a file path, not an image. There's no preview, no "apply to my render" here - you're expected to use the .cube elsewhere. If that surprises you, check the example workflow first so you know what "done" looks like.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| num_colors | INT | 171–256 | — |
| lut_size | INT | 172–64 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| lut_filepath | STRING | — |