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.
Currently prisma supports the following color models:
Rgb
- The standard color model for displaysRgi
- A chromaticity model constructed from Rgb that decouples chromaticity and lightnessHsv
- Hue, saturation, value: a more intuitive polar Rgb modelHsl
- Hue, saturation, lightness: an alternate to Hsv fulfilling similar rolesHsi
- Hue, saturation, intensity: a hue-based model without distortioneHsi
- An extension to Hsi
that rescaled saturation to avoid going out of gamut in RgbHwb
- Hue, whiteness, blackness: a hue-based model made to be easy for users to select colors inYCbCr
- A representation of the various YUV and YIQ models used in display and broadcastXyz
- The "parent" absolute color space other color spaces are defined in terms ofLms
- A color space simulating human cone responseLab
- A uniform perception color space transformation of XYZLchab
- A polar transformation of Lab. A uniform perception analog of HslLuv
- An alternative uniform perception color space useful in lighting calculationsLchuv
- A polar transformation of LuvPrisma also supports these color spaces with an alpha channel via the Alpha
type.
Currently, there are two main color libraries for rust:
color -- color
is a very old library that hasn't been updated in several years. While it
works for conversion through a few color spaces, and is easy to use, it has a very minimal set of features.
palette -- palette
has significantly more features and can go into a few of the CIE spaces,
but requiring all computations to be done in linear encoding is a serious drawback, as if you just
want a nice looking gradient in a game, linear Hsv will not get you that. It also is built on
predefined models and doesn't support dynamic configuration. prisma
supports
considerably more color spaces, as well as multiple encodings and spaces which can be built
at runtime. prisma
also does not require you to specify a color space, as most applications
don't really care and use the device color space or sRgb.
Prisma aims to support all the features of the above libraries, while making it up to the user how much complexity they need.
```rust
extern crate angular_units as angle;
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); ```
```rust
extern crate angular_units as angle;
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<_, Deglerp_flat
.
let rgbout = Rgb::fromcolor(&hsl1.lerp(&hsl2, 0.35));
assertrelativeeq!(rgb_out, Rgb::new(1.0, 0.045, 0.62648), epsilon=1e-4);
```
```rust
use prisma::Rgb;
let rgbin = Rgb::new(100, 200, 255u8);
let rgbout: Rgb
```rust
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);
```
```rust
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); ```