Expand description
§material-color-utils
A high-performance Rust port of Material Color Utilities.
This crate provides algorithms and utilities for working with Material 3 (M3) dynamic color, including the HCT color space, color quantization, and scheme generation.
§Core Concepts
- HCT (Hue, Chroma, Tone): A perceptually accurate color space that separates hue from lightness (tone).
- Dynamic Color: A system that generates adaptive, accessible color schemes based on a user’s source color.
- Materialized Theme: A flattened representation of a color scheme.
§Usage Examples
§High-Level Helpers (Simplified Theme Generation)
The easiest way to get started is with the high-level theme_from_color helper.
use material_color_utils::utils::color_utils::Argb;
use material_color_utils::theme_from_color;
// Create a theme from a source ARGB color
let source_color = Argb::from_hex("#4285F4").unwrap(); // Blue
// Builder with optional arguments for contrast, scheme variant, and more:
let theme = theme_from_color(source_color).call();
// Access light and dark schemes
let primary_light = theme.schemes.light.primary;
let primary_dark = theme.schemes.dark.primary;
println!("Light Primary: {}", primary_light);
println!("Dark Primary: {}", primary_dark);
// The materialized theme structs support serde (de)serialization
println!("Theme json: {}", serde_json::to_string_pretty(&theme).unwrap())§Color Extraction from Image
The image feature enables extracting prominent colors from images to use as source colors.
use material_color_utils::{extract_image_colors, theme_from_image};
let img = image::open("tests/assets/img/river.png").unwrap();
// Extract colors from an image
let colors = extract_image_colors(&img).call();
println!("Colors in 'river.png' to make a theme from: {:?}", colors);
// Generate a theme directly from an image
let theme = theme_from_image(&img).call().unwrap();§Dynamic API (HCT & Custom Schemes)
For more control, and lazy evaluation, you can work directly with the HCT color space and individual scheme builders.
use material_color_utils::hct::Hct;
use material_color_utils::scheme::SchemeTonalSpot;
use material_color_utils::dynamic::material_dynamic_colors::MaterialDynamicColors;
use material_color_utils::dynamic::color_spec::SpecVersion;
use material_color_utils::utils::color_utils::Argb;
// 1. Create a color in HCT space
let hct = Hct::from_argb(Argb(0xFF4285F4));
println!("H: {}, C: {}, T: {}", hct.hue(), hct.chroma(), hct.tone());
// 2. Manually build a scheme (Tonal Spot, Dark Mode, High Contrast)
let scheme = SchemeTonalSpot::builder(hct.to_argb(), true, 0.5)
.spec_version(SpecVersion::Spec2026)
.build();
// 3. Extract specific color roles using MaterialDynamicColors
let mdc = MaterialDynamicColors::new();
let primary = mdc.primary().get_argb(&scheme);
let on_primary = mdc.on_primary().get_argb(&scheme);
println!("Primary: {:?}", primary);
println!("On-Primary: {:?}", on_primary);§Contrast Helpers
Utilities for calculating contrast ratios and adjusting colors to meet accessibility standards.
use material_color_utils::utils::color_utils::Argb;
use material_color_utils::{get_contrast_ratio, lighter_tone, darker_tone, lighter_tone_unsafe, darker_tone_unsafe};
let color1 = Argb(0xFF4285F4);
let color2 = Argb::from_hex("#FFFFFF").unwrap();
// Calculate contrast ratio
let ratio = get_contrast_ratio(color1, color2);
println!("Contrast ratio: {:.2}", ratio);
// Find a color that meets a target contrast ratio
if let Some(lighter) = lighter_tone(color1, 4.5) {
println!("Lighter color with 4.5 contrast: {}", lighter);
}
// lighter_tone_unsafe will clip to white if it can't reach the desired contrast ratio.
let lighter_unsafe = lighter_tone_unsafe(color1, 4.5);
let darker_unsafe = darker_tone_unsafe(color1, 4.5);
println!("Lighter color, clipped if necessary at tone=100 (white): {}", lighter_unsafe);
println!("Darker color, clipped if necessary at tone=0 (black): {}", lighter_unsafe);§UI Integration
Dynamic colors are designed for lazy evaluation, allowing for high-performance, interfaces where only the colors used in the UI are calculated.
use material_color_utils::dynamic::dynamic_scheme::DynamicScheme;
use material_color_utils::dynamic::material_dynamic_colors::MaterialDynamicColors;
struct MyUIComponent {
scheme: DynamicScheme,
mdc: MaterialDynamicColors,
}
impl MyUIComponent {
fn on_render(&self) {
// Colors are evaluated on-demand from the current scheme
let bg = self.mdc.surface().get_argb(&self.scheme);
let primary = self.mdc.primary().get_argb(&self.scheme);
// ... apply bg and primary to UI elements ...
}
}Modules§
Structs§
- Extract
Image Colors Builder - Use builder syntax to set the inputs and finish with
call(). - Materialized
Scheme - Materialized
Scheme Group - Materialized
Theme - Theme
From Color Builder - Use builder syntax to set the inputs and finish with
call(). - Theme
From Image Builder - Use builder syntax to set the inputs and finish with
call(). - Themes
From Image Builder - Use builder syntax to set the inputs and finish with
call().
Functions§
- darker_
tone - Returns a darker color with tone >=
tonethat meetsratio, orNoneif impossible. - darker_
tone_ unsafe - Unsafe variant of
darker_tone: always returns a value in [0,100]. - extract_
image_ colors - Extract prominent colors from an image using quantization + scoring.
- get_
contrast_ ratio - Returns the contrast ratio of two colors.
- lighter_
tone - Returns a lighter color with tone >=
tonethat meetsratio, orNoneif impossible. - lighter_
tone_ unsafe - Unsafe variant of
lighter_tone: always returns a value in [0,100]. - theme_
from_ color - Generates a materialized theme from a source color.
- theme_
from_ image - Generate single theme from a source image.
- themes_
from_ image - Generate multiple themes from a source image.