Image Gradient Map
Recolor an image by its brightness
- image
- gradient_image
- IMAGE
A gradient map is the laziest impressive trick in image editing: instead of recoloring pixels by their own color, you throw their color away and recolor by brightness alone. Dark pixels take the first color of a ramp, bright pixels take the last, and everything in between lands somewhere along it. Feed a photo a black-to-orange ramp and you've got an instant posterized sunset look; feed it a navy-to-teal ramp and the whole frame goes moody without touching a single hue slider. Image Gradient Map is that, on the node, with a gradient you type yourself or steal from a picture.
It's from WAS Node Suite (WASasquatch's MIT pack, v3 ships 457 nodes), under WAS Suite/Image/Filter. Note the "Native": the original Image Gradient Map ran through OpenCV; this v3 replacement runs the same gradients on torch with nothing to install. Saved workflows under the old name load into it automatically.
The inputs
image- what gets recolored. Only its brightness is used; its own colors are discarded. A batch is handled one image at a time.gradient_stops- the ramp, one stop per line asposition:red,green,blue. Positions run 0 to 100 from shadows to highlights, channels 0 to 255. The default is0:0,0,0then100:255,255,255- plain black to white, which leaves the image's brightness roughly as-is while flattening it into the two colors. There's an editor on the node that writes into this field, and this string is what a saved run reads back.flip_left_right-falsemaps the ramp's first color to shadows and last to highlights. Flip it and the dark parts take the ramp's last color instead - a fast way to invert the mood of a duotone without retyping stops.
The optional gradient_image input lets you read a ramp that already exists as a picture instead of typing stops. It figures out which of the image's two axes travels furthest and reads along that one, averaging across the other - so a vertical gradient works as well as a horizontal one. A batch there pairs with the image batch frame by frame, which is how you'd drive a palette change across a sequence from a set of gradient images.
What comes out
One IMAGE - the recolored image at the same size as the source. That's the whole deal. It's a deterministic pixel op, so it's cheap to run, easy to A/B with different stop strings, and trivial to stack with other filters.
How to use it well
The gradient map's superpower is that it collapses a whole image to two or three colors while preserving all the shape - the luminance structure stays, so the image stays readable. That makes it a one-stop shop for:
- Duotone looks - two stops, one for shadow, one for highlight, and every stylized poster/film look in between.
- Brand/color-story matching - map a scene onto your palette's exact hex values instead of eyeballing a tint.
- Mood shifting - since only luminance matters, you can take a daytime shot and map it onto a night palette and the composition survives intact.
Because it discards color, it's also the honest answer when your image has a color cast you don't want to fight - there's nothing left of the cast to fight.
Install
WAS Node Suite via ComfyUI Manager (search "WAS Node Suite v3") or git clone https://github.com/WASasquatch/was-node-suite-comfyui into ComfyUI/custom_nodes, then restart. Needs ComfyUI 0.14.0+ and Python 3.10+; v3 installs no extra Python packages. If you open an old pre-v3 workflow whose Image Gradient Map is flagged missing, accept the replacement swap - it's the same node under the hood minus the OpenCV dependency.
Two quick gotchas. Only luminance is read, so two images with identical brightness but wildly different colors produce identical maps - check the luminance histogram if a map looks flatter than you expected. And if you connect gradient_image, gradient_stops is ignored entirely; disconnect it to go back to typed stops.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | The image to recolour. Only its brightness is used, so its own colours are discarded. A batch is handled one image at a time. | |
| flip_left_right | BOOLEAN | false | `true` sends the ramp's last colour to the shadows and its first to the highlights. `false` reads the ramp from its first colour to its last. |
| gradient_stops | STRING | 0:0,0,0 100:255,255,255 | One stop per line as position:red,green,blue, so '0:0,0,0' puts black in the shadows. Positions run 0 to 100 from shadows to highlights and channels 0 to 255. The editor below writes here, and this is what a run reads. Not used while gradient_image is connected. |
| gradient_imageopt | IMAGE | A gradient to read instead of the stops, for one that already exists as a picture. Whichever of its two axes travels furthest is the one read, averaged along the other, so a gradient running top to bottom works as well as one running left to right. A batch is paired with the image batch frame by frame. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The recoloured image, the same size as the source. |