image_palette
🎨 A Rust library for automatically extracting prominent color palettes from images.
Using octree algorithm, thanks for color-extraction.
Installation
To use image-palette in your Rust project, add it to your Cargo.toml.
[]
= "0.3"
To enable similar-color merging (recommended), enable the lab feature so that
distances are measured in the CIELAB color space, which matches human perception
much better than RGB:
[]
= { = "0.3", = ["lab"] }
Usage
Here is a basic example that demonstrates how to extract the color palette and find the dominant colors.
Advanced Options
Since v0.3.0, load_by_image_with_options gives you full control over extraction,
similar-color merging, ratio filtering and output size via [PaletteOptions].
PaletteOptions fields
| field | default | description |
|---|---|---|
extract_max |
16 |
OctTree internal bin count. Larger values distinguish closer colors. |
output_max |
8 |
Maximum number of colors returned. |
merge_delta_e |
10.0 |
CIELAB ΔE merge threshold. 0.0 disables merging. Requires the lab feature. |
min_ratio |
0.01 |
Minimum pixel ratio (in percent). Colors below this are dropped. |
Default usage
PaletteOptions::default() extracts up to 16 colors with the octree, merges
similar colors via agglomerative clustering, drops colors below 0.01% of
pixels, and returns at most 8 colors. Images with a flat or monotonous
palette will naturally yield fewer than 8 colors.
Merging is agglomerative clustering with centroid linkage: every octree
color starts as its own cluster, and the two closest clusters are repeatedly
merged until the nearest pair is farther apart than merge_delta_e. The
distance is a lightness-discounted CIE76:
ΔE' = sqrt((ΔL / 2)^2 + Δa^2 + Δb^2)
The lightness difference is halved, so a monotonous lightness gradient of the same hue (e.g. a brown paper texture from light tan to dark brown) collapses into a few representative colors (highlight / mid / shadow) instead of filling all 8 slots with barely distinguishable shades. Colors that differ mainly on the a/b axes — red vs blue, green vs orange — stay separate because their distance is dominated by Δa/Δb, which is not discounted.
use ;
let image = open.unwrap;
let = load_by_image_with_options.unwrap;
for color in &colors
Customizing options
Options use a builder pattern, so you only override what you need:
use PaletteOptions;
// Disable merging entirely (behave like the legacy API but still cap output)
let opts = default.with_merge_delta_e;
// Return up to 5 colors and only keep colors covering at least 1% of the image
let opts = default
.with_output_max
.with_min_ratio;
// Be more aggressive about merging similar colors
let opts = default.with_merge_delta_e;
Backward compatibility
The legacy APIs load, load_with_maxcolor and load_by_image_with_maxcolor
keep working exactly as before — they are equivalent to calling
load_by_image_with_options with merge_delta_e = 0.0, min_ratio = 0.0 and
output_max = extract_max (no merging, no ratio filtering, no truncation beyond
the requested color count). They do not require the lab feature.