Skip to content

Commit

Permalink
Merge branch 'mixing' into 'main'
Browse files Browse the repository at this point in the history
Rename interpolate to mix

See merge request Wacton/Unicolour!33
  • Loading branch information
waacton committed Oct 31, 2023
2 parents 546d5da + 82c5671 commit 99be8c2
Show file tree
Hide file tree
Showing 65 changed files with 2,521 additions and 2,511 deletions.
92 changes: 46 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Unicolour is a .NET library written in C# for working with colour:
- Colour space conversion
- Colour interpolation
- Colour mixing / colour interpolation
- Colour comparison
- Colour properties

Expand Down Expand Up @@ -76,30 +76,30 @@ It is also [extensively tested](Unicolour.Tests), including verification of roun
Targets [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0) for use in .NET 5.0+, .NET Core 2.0+ and .NET Framework 4.6.1+ applications.

## Quickstart ⚡
| Colour space | Construction | Access | Interpolation |
|-----------------------------------------|--------------------------|----------------|------------------------|
| RGB (Hex) | `Unicolour.FromHex()` | `.Hex` | `.InterpolateRgb()` |
| RGB (0-255) | `Unicolour.FromRgb255()` | `.Rgb.Byte255` | `.InterpolateRgb()` |
| RGB | `Unicolour.FromRgb()` | `.Rgb` | `.InterpolateRgb()` |
| HSB/HSV | `Unicolour.FromHsb()` | `.Hsb` | `.InterpolateHsb()` |
| HSL | `Unicolour.FromHsl()` | `.Hsl` | `.InterpolateHsl()` |
| HWB | `Unicolour.FromHwb()` | `.Hwb` | `.InterpolateHwb()` |
| CIEXYZ | `Unicolour.FromXyz()` | `.Xyz` | `.InterpolateXyz()` |
| CIExyY | `Unicolour.FromXyy()` | `.Xyy` | `.InterpolateXyy()` |
| CIELAB | `Unicolour.FromLab()` | `.Lab` | `.InterpolateLab()` |
| CIELCh<sub>ab</sub> | `Unicolour.FromLchab()` | `.Lchab` | `.InterpolateLchab()` |
| CIELUV | `Unicolour.FromLuv()` | `.Luv` | `.InterpolateLuv()` |
| CIELCh<sub>uv</sub> | `Unicolour.FromLchuv()` | `.Lchuv` | `.InterpolateLchuv()` |
| HSLuv | `Unicolour.FromHsluv()` | `.Hsluv` | `.InterpolateHsluv()` |
| HPLuv | `Unicolour.FromHpluv()` | `.Hpluv` | `.InterpolateHpluv()` |
| IC<sub>T</sub>C<sub>P</sub> | `Unicolour.FromIctcp()` | `.Ictcp` | `.InterpolateIctcp()` |
| J<sub>z</sub>a<sub>z</sub>b<sub>z</sub> | `Unicolour.FromJzazbz()` | `.Jzazbz` | `.InterpolateJzazbz()` |
| J<sub>z</sub>C<sub>z</sub>h<sub>z</sub> | `Unicolour.FromJzczhz()` | `.Jzczhz` | `.InterpolateJzczhz()` |
| Oklab | `Unicolour.FromOklab()` | `.Oklab` | `.InterpolateOklab()` |
| Oklch | `Unicolour.FromOklch()` | `.Oklch` | `.InterpolateOklch()` |
| CIECAM02 | `Unicolour.FromCam02()` | `.Cam02` | `.InterpolateCam02()` |
| CAM16 | `Unicolour.FromCam16()` | `.Cam16` | `.InterpolateCam16()` |
| HCT | `Unicolour.FromHct()` | `.Hct` | `.InterpolateHct()` |
| Colour space | Construction | Access | Interpolation |
|-----------------------------------------|--------------------------|----------------|----------------|
| RGB (Hex) | `Unicolour.FromHex()` | `.Hex` | `.MixRgb()` |
| RGB (0-255) | `Unicolour.FromRgb255()` | `.Rgb.Byte255` | `.MixRgb()` |
| RGB | `Unicolour.FromRgb()` | `.Rgb` | `.MixRgb()` |
| HSB/HSV | `Unicolour.FromHsb()` | `.Hsb` | `.MixHsb()` |
| HSL | `Unicolour.FromHsl()` | `.Hsl` | `.MixHsl()` |
| HWB | `Unicolour.FromHwb()` | `.Hwb` | `.MixHwb()` |
| CIEXYZ | `Unicolour.FromXyz()` | `.Xyz` | `.MixXyz()` |
| CIExyY | `Unicolour.FromXyy()` | `.Xyy` | `.MixXyy()` |
| CIELAB | `Unicolour.FromLab()` | `.Lab` | `.MixLab()` |
| CIELCh<sub>ab</sub> | `Unicolour.FromLchab()` | `.Lchab` | `.MixLchab()` |
| CIELUV | `Unicolour.FromLuv()` | `.Luv` | `.MixLuv()` |
| CIELCh<sub>uv</sub> | `Unicolour.FromLchuv()` | `.Lchuv` | `.MixLchuv()` |
| HSLuv | `Unicolour.FromHsluv()` | `.Hsluv` | `.MixHsluv()` |
| HPLuv | `Unicolour.FromHpluv()` | `.Hpluv` | `.MixHpluv()` |
| IC<sub>T</sub>C<sub>P</sub> | `Unicolour.FromIctcp()` | `.Ictcp` | `.MixIctcp()` |
| J<sub>z</sub>a<sub>z</sub>b<sub>z</sub> | `Unicolour.FromJzazbz()` | `.Jzazbz` | `.MixJzazbz()` |
| J<sub>z</sub>C<sub>z</sub>h<sub>z</sub> | `Unicolour.FromJzczhz()` | `.Jzczhz` | `.MixJzczhz()` |
| Oklab | `Unicolour.FromOklab()` | `.Oklab` | `.MixOklab()` |
| Oklch | `Unicolour.FromOklch()` | `.Oklch` | `.MixOklch()` |
| CIECAM02 | `Unicolour.FromCam02()` | `.Cam02` | `.MixCam02()` |
| CAM16 | `Unicolour.FromCam16()` | `.Cam16` | `.MixCam16()` |
| HCT | `Unicolour.FromHct()` | `.Hct` | `.MixHct()` |

## How to use 🌈
1. Install the package from [NuGet](https://www.nuget.org/packages/Wacton.Unicolour/)
Expand Down Expand Up @@ -169,28 +169,28 @@ var relativeLuminance = unicolour.RelativeLuminance;
var temperature = unicolour.Temperature;
```

6. Interpolate between colours:
6. Mix colours (interpolate between them):
```c#
var interpolated = unicolour1.InterpolateRgb(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateHsb(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateHsl(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateHwb(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateXyz(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateXyy(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateLab(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateLchab(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateLuv(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateLchuv(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateHsluv(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateHpluv(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateIctcp(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateJzazbz(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateJzczhz(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateOklab(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateOklch(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateCam02(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateCam16(unicolour2, 0.5);
var interpolated = unicolour1.InterpolateHct(unicolour2, 0.5);
var mixed = unicolour1.MixRgb(unicolour2, 0.5);
var mixed = unicolour1.MixHsb(unicolour2, 0.5);
var mixed = unicolour1.MixHsl(unicolour2, 0.5);
var mixed = unicolour1.MixHwb(unicolour2, 0.5);
var mixed = unicolour1.MixXyz(unicolour2, 0.5);
var mixed = unicolour1.MixXyy(unicolour2, 0.5);
var mixed = unicolour1.MixLab(unicolour2, 0.5);
var mixed = unicolour1.MixLchab(unicolour2, 0.5);
var mixed = unicolour1.MixLuv(unicolour2, 0.5);
var mixed = unicolour1.MixLchuv(unicolour2, 0.5);
var mixed = unicolour1.MixHsluv(unicolour2, 0.5);
var mixed = unicolour1.MixHpluv(unicolour2, 0.5);
var mixed = unicolour1.MixIctcp(unicolour2, 0.5);
var mixed = unicolour1.MixJzazbz(unicolour2, 0.5);
var mixed = unicolour1.MixJzczhz(unicolour2, 0.5);
var mixed = unicolour1.MixOklab(unicolour2, 0.5);
var mixed = unicolour1.MixOklch(unicolour2, 0.5);
var mixed = unicolour1.MixCam02(unicolour2, 0.5);
var mixed = unicolour1.MixCam16(unicolour2, 0.5);
var mixed = unicolour1.MixHct(unicolour2, 0.5);
```

7. Compare colours:
Expand Down
10 changes: 5 additions & 5 deletions Unicolour.Example/Gradient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ internal static class Gradient
{
const bool ConstrainUndisplayableColours = true; // if false, undisplayable colours will render as transparent

internal delegate Unicolour Interpolate(Unicolour start, Unicolour end, double distance);
internal delegate Unicolour Mix(Unicolour start, Unicolour end, double distance);

internal static Image<Rgba32> Draw((string text, Unicolour colour) label, int width, int height,
Unicolour[] colourPoints, Interpolate interpolate)
Unicolour[] colourPoints, Mix mix)
{
var image = new Image<Rgba32>(width, height);

Expand All @@ -21,20 +21,20 @@ internal static Image<Rgba32> Draw((string text, Unicolour colour) label, int wi
{
var startColour = colourPoints[sectionIndex];
var endColour = colourPoints[sectionIndex + 1];
SetSectionPixels(image, sectionWidth, sectionIndex, height, startColour, endColour, interpolate);
SetSectionPixels(image, sectionWidth, sectionIndex, height, startColour, endColour, mix);
}

SetLabel(image, label.text, label.colour);
return image;
}

private static void SetSectionPixels(Image<Rgba32> image, int sectionWidth, int sectionIndex, int height,
Unicolour startColour, Unicolour endColour, Interpolate interpolate)
Unicolour startColour, Unicolour endColour, Mix mix)
{
for (var pixelIndex = 0; pixelIndex < sectionWidth; pixelIndex++)
{
var distance = pixelIndex / (double)(sectionWidth - 1);
var colour = interpolate(startColour, endColour, distance);
var colour = mix(startColour, endColour, distance);
var column = sectionWidth * sectionIndex + pixelIndex;
SetImageColumnPixels(image, column, height, colour);
}
Expand Down
52 changes: 26 additions & 26 deletions Unicolour.Example/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void GenerateColourSpaceGradients()
var cyan = Unicolour.FromRgb255(0, 255, 255);
var black = Unicolour.FromRgb(0, 0, 0);
var green = Unicolour.FromRgb(0, 1, 0);

var light = Unicolour.FromHex("#E8E8FF");
var column1 = DrawColumn(new[] { purple, orange });
var column2 = DrawColumn(new[] { pink, cyan });
Expand All @@ -36,26 +36,26 @@ void GenerateColourSpaceGradients()

Image<Rgba32> DrawColumn(Unicolour[] colourPoints)
{
var rgb = Gradient.Draw(("RGB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateRgb(end, distance));
var hsb = Gradient.Draw(("HSB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateHsb(end, distance));
var hsl = Gradient.Draw(("HSL", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateHsl(end, distance));
var hwb = Gradient.Draw(("HWB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateHwb(end, distance));
var xyz = Gradient.Draw(("XYZ", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateXyz(end, distance));
var xyy = Gradient.Draw(("xyY", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateXyy(end, distance));
var lab = Gradient.Draw(("LAB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateLab(end, distance));
var lchab = Gradient.Draw(("LCHab", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateLchab(end, distance));
var luv = Gradient.Draw(("LUV", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateLuv(end, distance));
var lchuv = Gradient.Draw(("LCHuv", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateLchuv(end, distance));
var hsluv = Gradient.Draw(("HSLuv", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateHsluv(end, distance));
var hpluv = Gradient.Draw(("HPLuv", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateHpluv(end, distance));
var ictcp = Gradient.Draw(("ICtCp", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateIctcp(end, distance));
var jzazbz = Gradient.Draw(("JzAzBz", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateJzazbz(end, distance));
var jzczhz = Gradient.Draw(("JzCzHz", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateJzczhz(end, distance));
var oklab = Gradient.Draw(("OKLAB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateOklab(end, distance));
var oklch = Gradient.Draw(("OKLCH", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateOklch(end, distance));
var cam02 = Gradient.Draw(("CAM02", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateCam02(end, distance));
var cam16 = Gradient.Draw(("CAM16", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateCam16(end, distance));
var hct = Gradient.Draw(("HCT", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.InterpolateHct(end, distance));
var rgb = Gradient.Draw(("RGB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixRgb(end, distance));
var hsb = Gradient.Draw(("HSB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixHsb(end, distance));
var hsl = Gradient.Draw(("HSL", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixHsl(end, distance));
var hwb = Gradient.Draw(("HWB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixHwb(end, distance));
var xyz = Gradient.Draw(("XYZ", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixXyz(end, distance));
var xyy = Gradient.Draw(("xyY", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixXyy(end, distance));
var lab = Gradient.Draw(("LAB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixLab(end, distance));
var lchab = Gradient.Draw(("LCHab", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixLchab(end, distance));
var luv = Gradient.Draw(("LUV", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixLuv(end, distance));
var lchuv = Gradient.Draw(("LCHuv", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixLchuv(end, distance));
var hsluv = Gradient.Draw(("HSLuv", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixHsluv(end, distance));
var hpluv = Gradient.Draw(("HPLuv", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixHpluv(end, distance));
var ictcp = Gradient.Draw(("ICtCp", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixIctcp(end, distance));
var jzazbz = Gradient.Draw(("JzAzBz", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixJzazbz(end, distance));
var jzczhz = Gradient.Draw(("JzCzHz", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixJzczhz(end, distance));
var oklab = Gradient.Draw(("OKLAB", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixOklab(end, distance));
var oklch = Gradient.Draw(("OKLCH", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixOklch(end, distance));
var cam02 = Gradient.Draw(("CAM02", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixCam02(end, distance));
var cam16 = Gradient.Draw(("CAM16", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixCam16(end, distance));
var hct = Gradient.Draw(("HCT", light), columnWidth, rowHeight, colourPoints, (start, end, distance) => start.MixHct(end, distance));

var columnImage = new Image<Rgba32>(columnWidth, rowHeight * rows);
columnImage.Mutate(context => context
Expand Down Expand Up @@ -103,15 +103,15 @@ void GenerateVisionDeficiencyGradients()

var dark = Unicolour.FromHex("#404046");
var none = Gradient.Draw(("No deficiency", dark), width, rowHeight, colourPoints,
(start, end, distance) => start.InterpolateHsb(end, distance));
(start, end, distance) => start.MixHsb(end, distance));
var protanopia = Gradient.Draw(("Protanopia", dark), width, rowHeight, colourPoints,
(start, end, distance) => start.InterpolateHsb(end, distance).SimulateProtanopia());
(start, end, distance) => start.MixHsb(end, distance).SimulateProtanopia());
var deuteranopia = Gradient.Draw(("Deuteranopia", dark), width, rowHeight, colourPoints,
(start, end, distance) => start.InterpolateHsb(end, distance).SimulateDeuteranopia());
(start, end, distance) => start.MixHsb(end, distance).SimulateDeuteranopia());
var tritanopia = Gradient.Draw(("Tritanopia", dark), width, rowHeight, colourPoints,
(start, end, distance) => start.InterpolateHsb(end, distance).SimulateTritanopia());
(start, end, distance) => start.MixHsb(end, distance).SimulateTritanopia());
var achromatopsia = Gradient.Draw(("Achromatopsia", dark), width, rowHeight, colourPoints,
(start, end, distance) => start.InterpolateHsb(end, distance).SimulateAchromatopsia());
(start, end, distance) => start.MixHsb(end, distance).SimulateAchromatopsia());

var image = new Image<Rgba32>(width, rowHeight * rows);
image.Mutate(context => context
Expand Down
Loading

0 comments on commit 99be8c2

Please sign in to comment.