Crate colstodian
source ·Expand description
An opinionated color management library for games and graphics.
Introduction
Color is a really complex and fascinating topic, and I’d love to take you on a little tour
and show you how colstodian tries to help make it easier to manage. But, if you really just want to get
sh*t done right now, here’s the basics:
Color is a unified type representing a color in any ColorEncoding.
The ColorEncoding defines a bunch of different properties about how the
color values are stored and what those values actually mean. For example,
Color<SrgbU8> is a color with red, green, and blue values that vary from
0-255 and the meaning of those values is defined by the full sRGB color encoding standard.
The most common and standard color encodings are exposed in the basic_encodings module.
Many built-in color encodings expose constructor functions on the Color
type. See the docs for that type for a full list. The ones you are likely most interested in
if you don’t know much about color are:
Color::srgb_u8: If you have three0-255values, this is what you wantColor::srgb_f32: If you have three0.0..=1.0values, this is probably what you wantColor::linear_srgb: If you have three0.0..=1.0values that you know are “linear rgb”, this is probably what you want
If you also have alpha (i.e. four values instead of three), then Color::srgba_u8, Color::srgba_f32, and Color::linear_srgba
are the equivalents of the above with an alpha component.
If you want to do math to a color (for example, adding two colors together or multiplying one by a coefficient),
you’ll want to do so in a color encoding that is conducive to that. Color encodings which have this property implement
the WorkingEncoding trait. If a Color is not encoded in a working encoding,
it will not implement common math traits like addition, multiplication, etc.
The most common WorkingEncoding is LinearSrgb. You can convert a color you have created using any of the
constructors above to LinearSrgb by using the .convert::<E>() method.
If you want to output a color into an image file, the most common color encoding for most common image formats
(and the one assumed by viewing programs if a color profile is not embedded) is SrgbU8.
You can convert a color from a working encoding to SrgbU8 for output again with the .convert::<E>()
method.
Example
Here we construct two colors in different ways, convert them both to LinearSrgb to work with them, and then convert the result
to SrgbU8 which can be passed on to be displayed in an image.
use colstodian::Color;
use colstodian::basic_encodings::{SrgbU8, LinearSrgb};
let color1 = Color::srgb_u8(102, 54, 220);
let color2 = Color::srgb_f32(0.5, 0.8, 0.1);
let color1_working = color1.convert::<LinearSrgb>();
let color2_working = color2.convert::<LinearSrgb>();
let result_working = color1_working * 0.5 + color2_working;
let output = result_working.convert::<SrgbU8>();
assert_eq!(output, Color::srgb_u8(144, 206, 163));Color Encoding Basics
Much like how a 3d vector like a glam::Vec3 could be used to describe any of:
- The motion vector of an object in meters per second
- The position of an object relative to a reference point in kilometers
- Three “wellness scores” for a character, which each axis representing how happy the character is about some aspect of their life
A bag of components that describes “a color” could actually be interpreted in many different ways, and the end result of what those components mean is very different.
colstodian gathers all the information that defines how a color is represented in data as well as
what that data actually means into representative types that implement the ColorEncoding trait.
Modules
- Contains a basic set of
ColorEncodings to get most people going. - Contains advanced usage details of the crate.
Macros
- Assert that
$leftand$rightare equal within a margin of$eps.
Structs
- A strongly typed color, parameterized by a
ColorEncoding.
Traits
- A type that implements
ColorEncodingrepresents a collection of metadata that together defines how a color’s data is stored and what the values of that data actually mean. - Implemented by color encodings which are designed to be perceptually-uniform. In general these encodings will produce more visually pleasing results when blending between colors (for example, creating gradients) in many situations. However they are certainly not, silver bullets, and often don’t fully deliver on the promise of perceptual uniformity.
- Marks a type as representing a color encoding in which it makes sense to be able to perform mathematical operations on the contained color values directly.