Skip to content

GitHub go.mod Go version GitHub Release GitHub commit activity

Colorduce 🎥

A tool for generating a chromatic fingerprint of a video file, or a 'colorduction'. This project converts an entire video into a single, static image, providing a unique "at-a-glance" visualization of its color timeline and composition.

The generated image, or "colorduction", represents the video's entire duration. Each vertical column of pixels corresponds to a fixed fraction (e.g. one second of video), revealing the dominant colors and their evolution over time.


An example colorduction of a clip from Amelie Poulain, famous for its green and red color scheme.


🎯 Core Concept

The fundamental idea is to compress the temporal dimension of a video into a spatial one.

  • The X-axis represents Time: Each single-pixel-wide vertical column in the image corresponds to a specific interval of the video, the default being 1 second or 1/1920 of the total duration, whichever is the smallest. A 90-minute movie would therefore produce an image that is 5400 pixels (90x60) wide.
  • The Y-axis represents Color Distribution: Each vertical column is a sorted histogram of the most prominent colors present in that second of video.
    • Colors are consistently sorted by Hue (from red at the bottom to violet at the top, like a rainbow).
    • The vertical space (height) each color occupies is directly proportional to its prevalence in the frames of that second. A scene dominated by a blue sky will show a large blue band in its corresponding column.

The final output is a visually striking "chromatic timeline" that can be used to understand the video's color palette, pacing, and scene structure without watching it.


✨ Features

  • Video-to-Image Conversion: Processes any FFmpeg-compatible video file and outputs a high-resolution PNG or JPG image.
  • Color Palette Analysis: The image serves as a direct visualization of the director's color grading and palette choices throughout the film.
  • Scene Change Detection: Abrupt changes in color and composition between scenes are immediately visible as sharp vertical transitions in the image.
  • Customizable Granularity: While the default is one column per second, this can be adjusted to capture different levels of detail.

💡 Potential Applications

This visualization technique has several interesting use cases:

  • Film & Art Analysis: Study the color theory of directors like Wes Anderson or Denis Villeneuve by comparing the chromatic fingerprints of their films.
  • Video Summarization: Get a "feel" for a video's visual tone and pacing in seconds.
  • Data-Driven Editing: Identify major visual acts or sequences in a film based on sustained color patterns.
  • Combined Media Analysis: The generated image can be paired with an audio spectrogram of the same video to create a comprehensive audio-visual summary.

⚙️ The Technical Process

The program processes the video in a stream-like fashion to keep memory usage manageable. Here is a step-by-step breakdown of the algorithm for each second of video:

  1. Video Decoding: The tool uses a command-line pipe from FFmpeg to decode the video and stream raw pixel data (e.g., RGB24 format) frame by frame, avoiding the need to store individual image files on disk.
  2. Frame Buffering: All frames corresponding to a single one-second interval are collected.
  3. Color Sampling & Conversion: Every pixel (or a statistical sample of pixels) from the buffered frames is read and its color value is converted from the standard RGB model to the HSL (Hue, Saturation, Lightness) color model. HSL is ideal because it isolates the core color (Hue) from its brightness and intensity.
  4. Color Quantization (Bucketing): To manage the millions of potential colors, we group them into a manageable number of "buckets." This is done by creating a 3D histogram based on the HSL values:
    • Hue (H): Divided into N segments (e.g., 12 segments of 30° each).
    • Saturation (S): Divided into M segments (e.g., 5 segments of 20% each).
    • Lightness (L): Divided into K segments (e.g., 5 segments of 20% each). This creates a total of N x M x K possible color buckets. Each pixel from the video segment is placed into its corresponding bucket.
  5. Histogram Analysis: After processing all pixels for the one-second interval, the program counts the number of pixels in each bucket. It then selects the top X most populated buckets to represent that second.
  6. Column Generation: A single vertical column of pixels is drawn for the output image.
    • The selected buckets are sorted by their Hue band, the Saturation, the Luminance..
    • Each color is drawn as a vertical segment. The color used to represent it is the one in the 'center' of the 3D block it represents (the middle of the H-range, the S-range and the L-range). The height of the segment is proportional to its bucket's pixel count relative to the total count of all selected buckets.
  7. Image Assembly: This newly generated column is appended to the final image being built in memory. The process repeats from Step 2 for the next second of the video until the entire file is processed.
  8. Final Output: The completed image is saved to a file (e.g., output.png).

Implementation

for speed reasons, the input decoding is done by ffmpeg and the bucket counting and image generation is done in golang.


🚀 Usage

This tool is designed to be run from the command line.

Prerequisites: * FFmpeg must be installed and accessible in your system's PATH.

Example Command:

# Process a video file and generate an image with a height of 1080 pixels
./colorduce -i "path/to/my-movie.mp4" -o "output/output.png" -h 1080 -w 1920

Command-Line Flags

  • -i, --input <filepath>: (Required) Path to the source video file.
  • -o, --output <filepath>: (Required) Path where the output image will be saved.
  • -h, --height <pixels>: the desired height of the output image in pixels. Defaults to 1080. The width is automatically determined by the video's duration in seconds.
  • -w, --width <pixels>: the desired pixel width. default is 1920 or the # seconds, whichever is biggest. each vertical pixel colum will be calculated from (total_number_of_frames / total_width). if the input video is shorter than 1920 frames (80 seconds at 24 fps), then each color column
  • -c, --colorbands <integer>: the number of bands the H dimension (color or hue, expressed in 0-360 degrees) should be divided in. default is 10.
  • -s, --saturationbands <integer>: the number of bands the S dimension (saturation) should be divided in. the default is 5.
  • -l, --luminancebands <integer>: the number of bands the L dimension (luminance) should be divided in. the default is 5.
  • -b, --buckets <integer>: The top N buckets should be used as input for the vertical line. The default is 100.

Example

$ colorduce -i "amelie.mp4" -o "amelie-12-10-10-75.png" -h 1080 -w 1920 -c 12 -s 10 -l 10 -b 75

Processing: amelie.mp4 -> amelie-12-10-10-75.png
Input file      : examples/amelie.mp4
Input size      : 33.74 MB
Input Resolution: 1920x816
Input Duration  : 116.41 s
Input Bitrate   : 2243 kbps
Parallel workers: 10
100% 
Execution time: 20.94 s
Speed index: 5.56x

🤝 Contributing

Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.


📄 License

This project is licensed under the MIT License. See the LICENSE file for details.