FFmpeg CLUT: Map Monochrome to Color Gradient
This guide explains how to map a monochrome or grayscale image to a
custom color gradient using FFmpeg's clut (Color Look-Up
Table) filter. By pairing a grayscale source with a gradient image, you
can create false-color thermal maps, duotone aesthetics, and custom
stylized color grading directly from the command line.
How the CLUT Filter Works
The clut filter replaces pixel values of a primary video
or image stream using a secondary stream as a color lookup table. For
monochrome inputs, the luminance value of each pixel (from 0 to 255)
corresponds directly to a horizontal coordinate on the gradient
image:
- A pixel value of
0(pure black) samples the leftmost edge of the gradient. - A pixel value of
255(pure white) samples the rightmost edge of the gradient. - Midtones sample the intermediate colors proportionally across the horizontal axis.
Basic Mapping with an Existing Gradient
To apply a pre-made gradient image to a monochrome file, supply the
monochrome image as the first input (0:v) and the gradient
image as the second input (1:v):
ffmpeg -i input_mono.png -i gradient.png -filter_complex "[0:v][1:v]clut" output.pngFor accurate 8-bit mapping, the gradient file
(gradient.png) should ideally be a horizontal strip
measuring 256 pixels wide by 1 pixel high (256x1), though standard
multi-pixel horizontal gradients will also function.
Generating Gradients Directly in FFmpeg
You can generate a gradient dynamically without an external image
file by using FFmpeg's built-in gradients filter.
To create a duotone effect mapping from dark blue (shadows) to bright yellow (highlights):
ffmpeg -i input_mono.png -filter_complex \
"gradients=s=256x1:c0=0x000033:c1=0xFFFF00[grad]; \
[0:v][grad]clut" \
output.pngHandling Pixel Format Mismatches
The clut filter requires compatible pixel formats across
both inputs. If your source image is single-channel grayscale (such as
gray or gray8), convert both inputs to
standard RGB formats inside the filtergraph:
ffmpeg -i input_mono.png -i gradient.png -filter_complex \
"[0:v]format=rgb24[main]; \
[1:v]format=rgb24[lut]; \
[main][lut]clut" \
output.pngChanging Interpolation Modes
By default, the clut filter smoothly interpolates values
between color steps. If you want hard, posterized transitions without
intermediate blending, set the step option to
nearest:
ffmpeg -i input_mono.png -i gradient.png -filter_complex "[0:v][1:v]clut=step=nearest" output.png