colorimetry

Crates.iocolorimetry
lib.rscolorimetry
version0.0.8
created_at2024-08-02 03:38:00.585414+00
updated_at2025-09-06 03:28:25.868041+00
descriptionRust Spectral Colorimetry library with JavaScript/WASM interfaces
homepage
repositoryhttps://github.com/harbik/colorimetry
max_upload_size
id1322788
size2,946,486
(harbik)

documentation

README

Colorimetry

Build Status

This is a Rust library for working with color and light — great for projects in lighting, imaging, or anything that needs accurate color handling. It includes tools to simulate how colors look under different lights, convert between color spaces, and follow well-known standards from groups like the CIE, ICC, and IES. You can use it to build lighting tools, visualize spectra, or get the right transforms for your color profiles.

It also has early support for JavaScript and WebAssembly, so you can run it in the browser, and use it with JavaScript Runtimes such as Deno.

Usage

To use this library in a Rust application, run the command:

   cargo add colorimetry

or add this line to the dependencies in your Cargo.toml file:

    colorimetry = "0.0.7"

Examples

Calculate Tristimulus Values for Illuminants

This example calculates the XYZ tristimulus values of the D65 illuminant for both the CIE 1931 2º standard observer and the CIE 2015 10º observer.

  use colorimetry::illuminant::D65;

  // D65 Tristimulus values, using the CIE1931 standard observer by default
  let xyz_d65 = D65.xyz(None).set_illuminance(100.0);

  let [x, y, z] = xyz_d65.values();
  // [95.04, 100.0, 108.86]

  // D65 Tristimulus values using the CIE2015 10º observer
  use colorimetry::observer::Observer::Cie2015_10;
  let xyz_d65_10 = D65
    .xyz(Some(Cie2015_10)).set_illuminance(100.0);

  let [x_10, y_10, z_10] = xyz_d65_10.values();
  //[94.72, 100.0, 107.143]
Calculate Correlated Color Temperature and Tint

The correlated color temperature (CCT) of an illuminant, typically expressed in kelvin (K), describes whether a light source appears warm (low CCT) or cool (high CCT). It is a key parameter for characterizing the visual appearance of white light . This example calculates both the correlated color temperature and the deviation from the Planckian locus, often referred to as the tint.

  use colorimetry::illuminant::A;

  // Calculate CCT and Duv for the A illuminant
  // Requires `cct`, and `cie-illuminants` features
  let [cct, duv] = A.cct().unwrap().values();
  // [2855.4977, 0.0]
Calculate Color Fidelity Index for Illuminants

The CIE has announced that the Color Fidelity Index (CFI) will replace the Color Rendering Index (CRI) as the standard metric for evaluating color rendering. Both indices aim to quantify how accurately a light source reproduces the colors of illuminated objects. However, the CFI offers a significant improvement in accuracy by using 99 reference color samples and more advanced color difference metrics, compared to the CRI’s use of only 8 samples. Below is an example calculation of the general Color Fidelity Index for the CIE F2 illuminant:

  use colorimetry::illuminant::F2;

  // Calculate the Color Fidelity Index of the CIE F2 standard illuminant
  // Requires `cfi`, and `cie-illuminants` features
  let cf_f2 = F2.cfi().unwrap();
  let cf = cf_f2.general_color_fidelity_index();
  // 70.3
Calculate Spectral Locus to Plot in Diagrams

The spectral locus is the boundary in a chromaticity diagram that encloses all perceivable, physically realizable colors. Due to its shape, it is sometimes informally referred to as the "horseshoe." Below, we compute the chromaticity coordinates that define the spectral locus.

  use colorimetry::observer::Observer::Cie1931;
  let mut locus = Vec::new();
  let wavelength_range = Cie1931.spectral_locus_wavelength_range();
  for wavelength in wavelength_range {
    // unwrap OK because nm is in range
    let xyz = Cie1931.xyz_at_wavelength(wavelength).unwrap();
    let chromaticity = xyz.chromaticity();
    locus.push([wavelength as f64, chromaticity.x(), chromaticity.y()]);
  }
  println!("{locus:?}");
Calculate XYZ/RGB Transformation Matrices, for any Observer, for use in Color Profiles

This is usually done with the CIE 1931 Standard Observer, but this library supports any observer—as long as both the color space and the data use the same one. Instead of fixed XYZ values, it computes conversions from the spectral definitions of the primaries to be able to do so. Here, we compute transformation matrices for the DisplayP3 color space using both the Cie1931 and Cie2015 observers.

  use colorimetry::observer::Observer;
  use colorimetry::rgb::RgbSpace::DisplayP3;

  let xyz2rgb_31 = Observer::Cie1931.xyz2rgb_matrix(DisplayP3);
  //  2.4933, -0.9313, -0.4027,
  // -0.8298,  1.7629,  0.0236,
  //  0.0355, -0.076,   0.9574

  let rgb2xyz_31 = Observer::Cie1931.rgb2xyz_matrix(DisplayP3);
  // 0.4866, 0.2656, 0.1981,
  // 0.2291, 0.6917, 0.0792,
  // 0.0001, 0.0451, 1.0433,

  use colorimetry::observer::Observer::Cie2015;

  let xyz2rgb_15 = Cie2015.xyz2rgb_matrix(DisplayP3).clone();
  //  2.5258,  -1.0009, -0.3649,
  // -0.9006,   1.8546, -0.0011,
  //  0.0279,  -0.0574,  0.95874
Find the closest spectral match in the Munsell Color Book

This example finds the best matching color in the Munsell Color Book for a given sample—in this case, the R9 test color used in the CRI color rendering method. It uses the CieCam16::de_ucs color difference metric and the Cie2015_10 standard observer to calculate perceptual similarity.

The closest match identified is Munsell "5R 5/14", a vivid red hue, with a color difference of just 3 ΔE. In practical terms, a ΔE of 3 is considered a close match—just at the threshold where most observers might start to notice a difference under controlled viewing conditions.

  // requires `cri` and `munsell` features
  use colorimetry::observer::Observer::Cie2015_10;
  use colorimetry::colorant::{MunsellCollection, TCS};

  let cri_r9 = &TCS[8];
  let (key, delta_e) = MunsellCollection::match_ciecam16(
    cri_r9,
    None,
    None,
    Some(Cie2015_10),
  ).unwrap();
  // ("5R4/14", 2.85)
Match a paint color to a sRGB display value under realistic viewing conditions

This example matches the Munsell paint chip 5 BG 5/8—a teal/blue-green color— to its nearest sRGB rgb(0, 113, 138) equivalent, mimicking real-world viewing conditions.

Instead of the traditional CIE 1931 2° observer, this match uses the CIE 2015 10° observer, which more accurately reflects how paint colors appear on walls. The illumination is based on the warm-white LED_B2 standard illuminant (≈ 3000 K). Together, these adjustments help the display color reflect what you'd actually see on a freshly painted surface.

  // requires `cie-illuminants`, and `munsell` features
  use colorimetry::{
    cam::{ViewConditions, CIE248_HOME_SCREEN},
    colorant::Munsell,
    illuminant::LED_B2,
    observer::Observer::{Cie1931, Cie2015_10},
    rgb::RgbSpace::SRGB,
  };

  let paint = Munsell::try_new("5BG5/8").unwrap();
  let vc = ViewConditions::average_surround(6.0);
  let cam_paint = Cie2015_10.ciecam16(&LED_B2, &paint, vc);
  let rgb_2015 = cam_paint
    .rgb(SRGB, Some(CIE248_HOME_SCREEN))
    .unwrap()
    .compress();

  // Use a spectral representation of the Cie2015_10 RGB pixel, using the `Rgb`'s Light trait,
  // and calculate its XYZ tristimulus and RGB values for the CIE 1931 standard observer, the
  // observer
  // required for the sRGB color space.
  let xyz_1931 = Cie1931.xyz(&rgb_2015, None);
  let rgb_1931 = xyz_1931.rgb(SRGB).compress();
  let [r, g, b]: [u8; 3] = rgb_1931.into();
  //  (0, 113, 138)

Capabilities

  • Uses a Standard fixed-grid spectral representation Spectrum, with a wavelength domain ranging from 380 to 780 nanometers, with 1-nanometer intervals, ensuring high precision in capturing fine spectral details critical for accurate colorimetry calculations.

    • Uses nalgebra vector and matrix types for fast integration and transformations, chosen for its high performance, numerical stability, and compatibility with other mathematical libraries.
    • Supports interpolation from irregular spectral data using Spectrum::linear_interpolate and Spectrum::sprague_interpolate.
    • Optional smoothing using a Gaussian filter via Spectrum::smooth, which is typically used to reduce noise in spectral data or to smooth out irregularities in measured spectra for better analysis.
  • Generate spectral distributions from analytical models:

  • Includes Spectral Representations CIE Standard Illuminants (optional):

  • Includes Various Colorant Collections (optional):

    • Munsell Color System MunsellCollection, with over 1,000 colors
    • Color Evaluation Samples CES, a set of 99 test colors used in the Color Fidelity Index (CFI) calculations
  • Calculate Illuminant metrics:

    • CCT Correlated color temperature, including distance to the blackbody locus for tint indication1
    • CRI Color rendering index2
    • CFI Color fidelity index3
  • Use Advanced color (appearance) models:

  • Work with Spectrally based RGB color spaces, with support for non-CIE 1931 observers and generic transformations between Rgb and XYZ:

  • Includes Multiple CIE Standard Observers (see Observer), with transformations to XYZ:

  • Compute gamut boundaries for CIE XYZ (RelXYZGamut) and CIELAB (CieLChGamut) using optimal colors (OptimalColors).

    • Estimate the total number of perceptually distinct colors.
    • Plot CIE LCh iso-hue lines and iso-lightness contours on chromaticity diagrams.
    • Plot maximum luminance value contours on chromaticity diagrams.
    • Use in hue-neutral gamut-compression algorithms.

Features

  • cie-illuminants The D65 and D50 illuminants are always included - if you want to use one of the other CIE illuminants, set this feature flag.

  • munsell Include reflection spectra for Munsell colors.

  • cct Calculates correlated color temperatures (CCT) for illuminants. Generates a 4096-entry lookup table (each entry containing three f64 values). Memory is reserved at compile time but computed on demand. (Included automatically if the cri feature is enabled).

  • cri Enables Color Rendering Index (CRI) calculations, providing Ra and R1–R14 values for illuminants. Loads an additional 14 test color sample spectra.

  • cfi Enables Color Fidelity Index (CRI) calculations, providing Rf and Rf,1–Rf,99 values for illuminants. Loads the 99 CES test color sample spectra.

How to enable a feature?

To enable a feature, such as cri and munsell, use

cargo add colorimetry -F cri,munsell

or, if you prefer to use the cargo add command with the --features flag, you can run:

cargo add colorimetry --features cri,munsell

Alternatively, configure features manually in your Cargo.toml:

colorimetry = { version = "0.0.7", features = ["cri", "munsell"] }

Command Line Tool

This library has an associated command-line tool, named color, contained in the "colorimetry-cli" crate. It provides a convenient way to perform colorimetric calculations, convert spectral data, and make color plots directly from the terminal.

To use it you have to install it using cargo, which in turn requires that you have Rust and Cargo installed. Install them first by following the instructions at https://www.rust-lang.org/tools/install. After having done this, run the following command:

cargo install colorimetry-cli

That should be it, you can now use the color command in your terminal. Run the following command to see the available options and features for the colorimetry tool:

color --help

Color Plots

The colorimetry library includes a plotting module, in an associated colorimetry-plot crate that can be used to generate a number of color diagrams, spectral plots, and color rendering visulizations. It's ouput is in SVG format, which can be viewed in any modern web browser or vector graphics editor, such as Inkscape. The colorimetry-plot crate is not included by default, so you need to add it to your project using the following command:

cargo add colorimetry-plot

You can then use the colorimetry-plot crate to generate color plots.

Developer Tasks with xtask

This project uses a Rust-based xtask utility for common development tasks:

  • cargo xtask check – to run clippy, fmt, check, and readme verification,
  • cargo xtask test – test various feature configurations,
  • cargo xtask doc – build and open project documentation (fails on warnings), and,
  • cargo xtask wasm – to generate the web-assembly files in pkg (requires wasm-pack and wasm-opt)

More commands will be added as the project evolves.

License

All content ©2025 Harbers Bik LLC, and licensed under either of the

at your option.

Contribution

Unless you explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Footnotes

  1. McCamy, C. S. (1992). Correlated color temperature as an explicit function of chromaticity coordinates. Color Research & Application, 17(2), 142-144.

  2. Wyszecki, G., & Stiles, W. S. (2000). Color science: concepts and methods, quantitative data and formulae. John Wiley & Sons.

  3. Li, C., Luo, M. R., & Cui, G. (2020). The CIE 2017 colour fidelity index for accurate scientific use. Optics express, 28(5), 6589-6609.

Commit count: 509

cargo fmt