Unicolour
🌈 Colour / Color conversion, interpolation, and comparison for .NET
Install / Use
/learn @waacton/UnicolourREADME
<img src="https://gitlab.com/Wacton/Unicolour/-/raw/main/Unicolour/Resources/Unicolour.png" width="32" height="32"> Unicolour
Unicolour is the most comprehensive .NET library for working with colour:
- Colour space conversion
- Colour mixing / colour interpolation
- Colour blending
- Colour difference / colour distance
- Colour gamut mapping
- Colour chromaticity
- Colour temperature
- Wavelength attributes
- Pigments for natural paint mixing
- ICC profiles for CMYK conversion
Written in C# with zero dependencies and fully cross-platform compatible.
Targets .NET Standard 2.0 for use in .NET 5.0+, .NET Core 2.0+ and .NET Framework 4.6.1+ applications.
See a live demo in the browser — a colour picker for any colour space, including print (CMYK · ICC profiles) and paint (RYB · pigments) — made with Unicolour.
Contents
- 🧭 Overview
- 🔆 Installation
- ⚡ Quickstart
- 🌈 Features
- 💡 Configuration
- ✨ Examples
- 🔮 Datasets
- 🥽 Experimental
🧭 Overview
A Unicolour encapsulates a single colour and its representation across 40 colour spaces.
It can be used to mix and compare colours, and offers many useful features for working with colour.
[!NOTE] Supported colour spaces
RGB · Linear RGB · HSB / HSV · HSL · HWB · HSI · CIEXYZ · CIExyY · WXY · CIELAB · CIELCh<sub>ab</sub> · CIELUV · CIELCh<sub>uv</sub> · HSLuv · HPLuv · YPbPr · YCbCr / YUV (digital) · YCgCo · YUV (PAL) · YIQ (NTSC) · YDbDr (SECAM) · TSL · XYB · LMS · IPT · IC<sub>T</sub>C<sub>P</sub> · J<sub>z</sub>a<sub>z</sub>b<sub>z</sub> · J<sub>z</sub>C<sub>z</sub>h<sub>z</sub> · Oklab · Oklch · Okhsv · Okhsl · Okhwb · Okl<sub>r</sub>ab · Okl<sub>r</sub>ch · CIECAM02 · CAM16 · HCT · Munsell HVC · CMYK / ICC Profile <sup>?</sup>
Unicolour pink = new("#FF1493"); Console.WriteLine(pink.Oklab); // 0.65 +0.26 -0.01
This library was initially written for personal projects since existing libraries had complex APIs, missing features, or inaccurate conversions. The goal of this library is to be accurate, intuitive, and easy to use. Although performance is not a priority, conversions are only calculated once; when first evaluated (either on access or as part of an intermediate conversion step) the result is stored for future use.
Unicolour is extensively tested, including verification of roundtrip conversions, validation using known colour values, and 100% line coverage and branch coverage.
🔆 Installation
- Install the package from NuGet
dotnet add package Wacton.Unicolour
- Import the package
using Wacton.Unicolour;
- Use the package
Unicolour colour = new(ColourSpace.Rgb255, 192, 255, 238);
⚡ Quickstart
The simplest way to get started is to make a Unicolour and use it to see how the colour is represented in a different colour space.
var cyan = new Unicolour("#00FFFF");
Console.WriteLine(cyan.Hsl); // 180.0° 100.0% 50.0%
var yellow = new Unicolour(ColourSpace.Rgb255, 255, 255, 0);
Console.WriteLine(yellow.Hex); // #FFFF00
Colours can be mixed or interpolated using any colour space.
var red = new Unicolour(ColourSpace.Rgb, 1.0, 0.0, 0.0);
var blue = new Unicolour(ColourSpace.Hsb, 240, 1.0, 1.0);
/* RGB: [1, 0, 0] ⟶ [0, 0, 1] = [0.5, 0, 0.5] */
var purple = red.Mix(blue, ColourSpace.Rgb);
Console.WriteLine(purple.Rgb); // 0.50 0.00 0.50
Console.WriteLine(purple.Hex); // #800080
/* HSL: [0, 1, 0.5] ⟶ [240, 1, 0.5] = [300, 1, 0.5] */
var magenta = red.Mix(blue, ColourSpace.Hsl);
Console.WriteLine(magenta.Rgb); // 1.00 0.00 1.00
Console.WriteLine(magenta.Hex); // #FF00FF
// #FF0000, #FF0080, #FF00FF, #8000FF, #0000FF
var palette = red.Palette(blue, ColourSpace.Hsl, 5);
Console.WriteLine(palette.Select(colour => colour.Hex));
The difference or distance between colours can be calculated using any delta E metric.
var white = new Unicolour(ColourSpace.Oklab, 1.0, 0.0, 0.0);
var black = new Unicolour(ColourSpace.Oklab, 0.0, 0.0, 0.0);
var difference = white.Difference(black, DeltaE.Ciede2000);
Console.WriteLine(difference); // 100.0000
Other useful colour information is available, such as chromaticity coordinates, temperature, and dominant wavelength.
var equalEnergy = new Unicolour(ColourSpace.Xyz, 0.5, 0.5, 0.5);
Console.WriteLine(equalEnergy.RelativeLuminance); // 0.5
Console.WriteLine(equalEnergy.Chromaticity.Xy); // (0.3333, 0.3333)
Console.WriteLine(equalEnergy.Chromaticity.Uv); // (0.2105, 0.3158)
Console.WriteLine(equalEnergy.Temperature); // 5455.5 K (Δuv -0.00442)
Console.WriteLine(equalEnergy.DominantWavelength); // 596.1
Reference white points (e.g. D65) and the RGB model (e.g. sRGB) can be configured.
🌈 Features
Convert between colour spaces
Unicolour calculates all transformations required to convert from one colour space to any other, so there is no need to manually chain multiple functions and removes the risk of rounding errors.
Unicolour colour = new(ColourSpace.Rgb255, 192, 255, 238);
var (l, c, h) = colour.Oklch;
[!TIP]
RGB colours can also be constructed using their hex values:
Unicolour pink = new("ff1493"); var hex = pink.Hex; // #FF1493
| Colour space | Enum | Property |
|-----------------------------------------------------------------------------------------|-------------------------|----------------|
| RGB (0–255) | ColourSpace.Rgb255 | .Rgb.Byte255 |
| RGB | ColourSpace.Rgb | .Rgb |
| Linear RGB | ColourSpace.RgbLinear | .RgbLinear |
| HSB / HSV | ColourSpace.Hsb | .Hsb |
| HSL | ColourSpace.Hsl | .Hsl |
| HWB | ColourSpace.Hwb | .Hwb |
| HSI | ColourSpace.Hsi | .Hsi |
| CIEXYZ | ColourSpace.Xyz | .Xyz |
| CIExyY | ColourSpace.Xyy | .Xyy |
| WXY | ColourSpace.Wxy | .Wxy |
| CIELAB | ColourSpace.Lab | .Lab |
| CIELCh<sub>ab</sub> | ColourSpace.Lchab | .Lchab |
| CIELUV | ColourSpace.Luv | .Luv |
| CIELCh<sub>uv</sub> | ColourSpace.Lchuv | .Lchuv |
| HSLuv | ColourSpace.Hsluv | .Hsluv |
| HPLuv | ColourSpace.Hpluv | .Hpluv |
| YPbPr | ColourSpace.Ypbpr | .Ypbpr |
| YCbCr / YUV (digital) | ColourSpace.Ycbcr | .Ycbcr |
| YCgCo | ColourSpace.Ycgco | .Ycgco |
| YUV (PAL) | ColourSpace.Yuv | .Yuv |
| YIQ (NTSC) | ColourSpace.Yiq | .Yiq |
| YDbDr (SECAM)
