Prisma - The Rust Color Library

Build Status

Table of Contents:

Overview:

Prisma is a rust library aimed to be a comprehensive set of color representations, manipulations, conversions and algorithms that are easy to use for projects of all levels. Prisma follows a model of "opt-in" complexity, meaning that if you just want a library to convert from Rgb to Hsv and back, prisma will let you do it with minimal knowledge of color science. If you need to access the CIE spaces or do color space conversions however, prisma also provides that functionality with wrappers to use the type system to enforce validity.

Prisma aims to be the go-to source for color conversions and color science in rust. It is currently a work in progress, and any contributions or feature requests are appreciated.

Color Models:

Currently prisma supports the following color models:

Device Dependent:

Device Independent:

Prisma also supports these color spaces with an alpha channel via the Alpha type.

Why Prisma?

Currently, there are two main color libraries for rust:

Prisma aims to support all the features of the above libraries, while making it up to the user how much complexity they need.

A Tour by Example:

Converting from Rgb to Hsv, manipulating hue, and converting back

```rust

[macro_use] extern crate approx;

extern crate angular_units as angle;

extern crate prisma;

use prisma::{Rgb, Hsv, FromColor}; use angle::Deg;

let rgb = Rgb::new(0.5, 0.75, 1.0); let mut hsv = Hsv::fromcolor(&rgb); hsv.sethue(Deg(180.0)); let rgb = Rgb::fromcolor(&hsv); assertrelative_eq!(rgb, Rgb::new(0.5, 1.0, 1.0), epsilon=1e-6); ```

Interpolating between two colors in Hsl.

```rust

[macro_use] extern crate approx;

extern crate angular_units as angle;

extern crate prisma;

use prisma::{Rgb, Hsl, FromColor, Lerp}; use angle::Deg;

let rgb1 = Rgb::new(0.8, 0.25, 0.0f32); let rgb2 = Rgb::new(0.5, 0.66, 1.0); // Specify the hue channel should use degrees let hsl1: Hsl<_, Deg> = Hsl::fromcolor(&rgb1); let hsl2 = Hsl::fromcolor(&rgb2); // Note that hue channels will interpolate in the shortest direction. This is usually // the expected behavior, but you can always go forward with lerp_flat. let rgbout = Rgb::fromcolor(&hsl1.lerp(&hsl2, 0.35)); assertrelativeeq!(rgb_out, Rgb::new(1.0, 0.045, 0.62648), epsilon=1e-4); ```

Converting from Rgb to Rgb

```rust

[macro_use] extern crate approx;

extern crate prisma;

use prisma::Rgb;

let rgbin = Rgb::new(100, 200, 255u8); let rgbout: Rgb = rgbin.colorcast(); assertrelativeeq!(rgb_out, Rgb::new(0.39216, 0.78431, 1.0), epsilon=1e-4); ```

Convert from sRgb encoded to linear encoded Rgb

```rust

[macro_use] extern crate approx;

extern crate prisma;

use prisma::Rgb; use prisma::encoding::{EncodableColor, TranscodableColor, SrgbEncoding};

// This returns a EncodedColor<Rgb<f32>, SrgbEncoding> // Note: no encodind is done. srgb_encoded says that this value is already in sRgb encoding. let rgbsrgb = Rgb::new(0.5, 1.0, 0.25f32).srgbencoded(); // Decode goes from an encoding to linear. let rgblinear = rgbsrgb.clone().decode(); assertrelativeeq!(rgblinear, Rgb::new(0.21404, 1.0, 0.05088).linear(), epsilon=1e-4); // We can then go back with encode let rgbout = rgblinear.encode(SrgbEncoding); assertrelativeeq!(rgbout, rgb_srgb, epsilon=1e-6); ```

Going to XYZ

```rust

[macro_use] extern crate approx;

extern crate prisma;

use prisma::{Rgb, Xyz}; use prisma::encoding::{EncodableColor, TranscodableColor}; use prisma::colorspace::{ColorSpace, EncodedColorSpace, NamedColorSpace, ConvertToXyz}; use prisma::colorspace::presets::sRgb;

let rgb = Rgb::new(0.25, 0.5, 0.75f32).srgbencoded(); let colorspace = sRgb::getcolorspace(); // In this case, since rgb and colorspace know their own encodings, the conversion to linear // is automatic. let xyz = colorspace.converttoxyz(&rgb); assertrelativeeq!(xyz, Xyz::new(0.191803, 0.201605, 0.523050), epsilon=1e-5); ```