mcu-material-color

Crates.iomcu-material-color
lib.rsmcu-material-color
version0.2.0
created_at2026-01-24 19:57:31.198044+00
updated_at2026-01-24 19:57:31.198044+00
descriptionRust port of Google's Material Color Utilities - facade crate
homepagehttps://github.com/5ocworkshop
repositoryhttps://github.com/5ocworkshop
max_upload_size
id2067373
size144,283
(5ocworkshop)

documentation

README

mcu-material-color

A Rust port of Google's Material Color Utilities library for generating dynamic color schemes based on Material Design 3.

This is a fresh 2026 port of the latest Google library, including the 2025 Material Design spec updates with new color roles and improved algorithms.

Minimum Supported Rust Version (MSRV): 1.82

Features

  • HCT Color Space - Perceptually uniform color representation combining CAM16 and Lab*
  • Dynamic Color Schemes - Nine built-in scheme variants (TonalSpot, Vibrant, Expressive, etc.)
  • Image Quantization - Extract dominant colors from images using Celebi's algorithm
  • Accessibility - WCAG contrast calculations and accessible tone selection
  • Color Blending - Harmonize and blend colors in perceptually uniform spaces
  • Temperature Analysis - Find complementary and analogous colors

Quick Start

Add to your Cargo.toml:

[dependencies]
mcu-material-color = "0.2"

Generate a color scheme from a seed color:

use mcu_material_color::prelude::*;

// Create a scheme from a seed color (ARGB format)
let seed_color = 0xFF6750A4; // Purple
let hct = Hct::from_int(seed_color);
let scheme = SchemeTonalSpot::new(hct, false, 0.0);

// Access palette tones
let primary_40 = scheme.primary_palette.tone(40);
let surface_90 = scheme.neutral_palette.tone(90);

Extract colors from an image:

use mcu_material_color::prelude::*;

// Image pixels as ARGB u32 values
let pixels: Vec<u32> = load_image_pixels(); // Your image loading code

// Quantize to find dominant colors
let color_counts = QuantizerCelebi::quantize(&pixels, 128);

// Score and rank for theme suitability
let ranked_colors = Score::score(&color_counts);

// Use top color as theme seed
if let Some(&top_color) = ranked_colors.first() {
    let scheme = SchemeTonalSpot::new(Hct::from_int(top_color), false, 0.0);
}

Crate Organization

This workspace contains modular crates that can be used independently:

Crate Description
mcu-material-color Facade crate with all re-exports and prelude
mcu-hct HCT color space (Hue, Chroma, Tone) based on CAM16
mcu-palettes Tonal and core palette generation
mcu-scheme Pre-built color scheme variants
mcu-dynamiccolor Dynamic color system with runtime resolution
mcu-blend Color blending in HCT and CAM16-UCS spaces
mcu-contrast WCAG accessibility contrast calculations
mcu-quantize Image color quantization algorithms
mcu-score Color ranking for theme suitability
mcu-dislike Detection and correction of unfavorable colors
mcu-temperature Color temperature and analogous color calculations
mcu-utils Foundation math, color conversion, and string utilities

Key Types

Hct

The fundamental color type representing colors in HCT (Hue, Chroma, Tone) space:

use mcu_material_color::Hct;

// Create from ARGB
let hct = Hct::from_int(0xFFFF0000); // Red
println!("Hue: {}, Chroma: {}, Tone: {}", hct.hue(), hct.chroma(), hct.tone());

// Create from HCT values
let hct = Hct::from(180.0, 50.0, 60.0); // Cyan-ish at medium lightness

// Convert back to ARGB
let argb = hct.to_int();

TonalPalette

Generate consistent color tones from a single hue:

use mcu_material_color::TonalPalette;

let palette = TonalPalette::from_int(0xFF6200EE); // Deep Purple

// Get specific tones (0-100)
let light = palette.tone(90);  // Very light
let medium = palette.tone(40); // Medium
let dark = palette.tone(10);   // Very dark

Scheme Variants

Nine pre-built scheme variants for different design needs:

use mcu_material_color::prelude::*;

let source = Hct::from_int(0xFF0000FF);

// Default Material Design 3 style
let tonal_spot = SchemeTonalSpot::new(source, false, 0.0);

// High chroma, bold colors
let vibrant = SchemeVibrant::new(source, false, 0.0);

// Playful with hue shifts
let expressive = SchemeExpressive::new(source, false, 0.0);

// Grayscale
let monochrome = SchemeMonochrome::new(source, false, 0.0);

// True to source color
let fidelity = SchemeFidelity::new(source, false, 0.0);

All schemes support:

  • Light/dark mode (is_dark parameter)
  • Contrast levels from -1.0 (minimum) to 1.0 (maximum)
  • Platform variants (Phone, Watch)
  • Spec versions (2021, 2025)

QuantizerCelebi

Extract dominant colors from images:

use mcu_material_color::QuantizerCelebi;

let pixels = vec![0xFFFF0000, 0xFFFF0000, 0xFF00FF00, 0xFF0000FF];
let result = QuantizerCelebi::quantize(&pixels, 128);

// Result maps ARGB colors to occurrence counts
for (color, count) in &result {
    println!("Color {:08X}: {} pixels", color, count);
}

Color Blending

Harmonize accent colors with your theme:

use mcu_material_color::Blend;

let red = 0xFFFF0000;
let blue = 0xFF0000FF;

// Subtle hue shift towards blue (max 7.5 degrees)
let harmonized = Blend::harmonize(red, blue);

// Blend in perceptually uniform space
let blended = Blend::cam16_ucs(red, blue, 0.5);

Contrast & Accessibility

Calculate and ensure WCAG-compliant contrast:

use mcu_material_color::Contrast;

// Calculate contrast ratio between two tones
let ratio = Contrast::ratio_of_tones(40.0, 90.0);

// Find a lighter tone that meets contrast requirement (4.5 for AA)
let lighter = Contrast::lighter(40.0, 4.5);

// Find a darker tone
let darker = Contrast::darker(90.0, 4.5);

Resources

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

This is a Rust port of Google's Material Color Utilities, Copyright 2021 Google LLC, also licensed under Apache 2.0.

Commit count: 0

cargo fmt