Image Color Grade π¨
Exposure through tint, all in the right order
- image
- image
- grade_info
Your sampled image is close but flat, or too warm, or just needs that final photographic pass. That's what grading is, and this node crams the whole toolkit into one node with eight sliders and a sane pipeline order. It's the "don't leave ComfyUI for a compositor just to fix the color" node.
The eight inputs map to a real grading pipeline, applied in this specific order: exposure (multiplicative stop adjustment, so +1.0 doubles brightness), lift/gain (shadow lift and highlight gain), gamma (midtone power curve), contrast (pivoted around mid-grey), saturation (blend toward luminance), temperature (warm/cool, red vs blue), and tint (green vs magenta). Every default is a no-op - exposure 0, everything else 1, temp/tint 0 - so you start neutral and dial in what you actually need. Outputs are the graded image and a grade_info string that echoes your settings back, which is handy for comparing grades or logging.
The pipeline order matters more than people expect, and this is where knowing the primitives pays off. Gamma is a power curve, not an additive brightness - it lifts shadows without moving your whites, which is why it reads as a "proper" exposure change while additive brightness washes everything out. Contrast pivots around 0.5 so it never shifts overall brightness. Saturation happens after contrast, so you're saturating the graded image, not fighting it. The sequence is exactly the one a photo editor applies in its color panel, and getting it in one node means you don't have to wire four separate filter nodes and pray about ordering.
The honest take: it's a deterministic pixel operation, not a model - milliseconds, fully reproducible, and usually the right tool when an image just needs its levels fixed. The failure mode this kind of node prevents is doing color correction by re-rolling the generation (img2img), which burns a diffusion pass and a seed lottery on work a lookup curve does perfectly. If the look you want is more than "nicer levels" - say a deliberate film-print emulation or heavy stylization - you'd reach for a LoRA or a LUT instead; this node is the finishing pass, not the character.
One thing worth knowing before you over-slide: it operates on the RGB values directly, so extreme exposure or gain will clip highlights (values clamp to 1.0) rather than roll off smoothly. That's standard for a linear grading tool - if you need highlight roll-off or tone mapping, you want a tonemap step. For normal ranges - an exposure stop here, a touch of warmth there - it behaves exactly like you'd expect a photo editor to.
Install
Part of OmniNodes:
cd ComfyUI/custom_nodes
git clone https://github.com/TensorVizion/OmniNodes
Restart ComfyUI, or install "OmniNodes" via ComfyUI Manager. No extra dependencies - pure PyTorch.
Troubleshooting
- Image gets crushed/blown out fast -
exposureandgainclip at the extremes. Dial them back; usegammaorcontrastfor gentler moves. - Grade looks different between runs - it shouldn't; this is fully deterministic. If it changed, something upstream (a seed) changed.
- Where's this node in the menu? -
TensorVizion/Imagein the node search.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| exposure | FLOAT | 0.00-3β3 | β |
| contrast | FLOAT | 1.000β2 | β |
| saturation | FLOAT | 1.000β2 | β |
| gamma | FLOAT | 1.000.1β3 | β |
| lift | FLOAT | 0.00-0.5β0.5 | β |
| gain | FLOAT | 1.000.5β2 | β |
| temperature | FLOAT | 0.00-1β1 | β |
| tint | FLOAT | 0.00-1β1 | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | β |
| grade_info | STRING | β |