Skip to content

Commit

Permalink
Replaced OriginalWithModel ColorConverter with Gamut ColorConverter
Browse files Browse the repository at this point in the history
  • Loading branch information
michielpost committed Mar 22, 2019
1 parent fe7617c commit 239fa79
Show file tree
Hide file tree
Showing 16 changed files with 414 additions and 283 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Q42.HueApi.ColorConverters.OriginalWithModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Q42.HueApi.ColorConverters.Gamut;
using Q42.HueApi.Models.Gamut;
using System;

namespace Q42.HueApi.ColorConverters.Tests
Expand All @@ -17,12 +18,12 @@ public void ColorConversionWhitePoint()
foreach (string model in models)
{
// Make sure that Philips' white point resolves to #FFFFFF for all lights.
var rgb = HueColorConverter.XYToRgb(CIE1931Point.PhilipsWhite, model);
var rgb = HueColorConverter.XYToRgb(CIE1931Point.PhilipsWhite, CIE1931Gamut.ForModel(model));
Assert.AreEqual(rgb.R, 1.0, 0.0001);
Assert.AreEqual(rgb.G, 1.0, 0.0001);
Assert.AreEqual(rgb.B, 1.0, 0.0001);

var xy = HueColorConverter.RgbToXY(new RGBColor(1.0, 1.0, 1.0), model);
var xy = HueColorConverter.RgbToXY(new RGBColor(1.0, 1.0, 1.0), CIE1931Gamut.ForModel(model));
AssertAreEqual(CIE1931Point.PhilipsWhite, xy, 0.0001);
}
}
Expand Down Expand Up @@ -51,8 +52,8 @@ public void ColorsOutsideGamutAdjustedToInBeInGamutOnConversion()
// A color green outside Gamut A.
CIE1931Point greenOutsideGamut = new CIE1931Point(0.21, 0.75);

var a = HueColorConverter.XYToRgb(gamutGreen, "LST001");
var b = HueColorConverter.XYToRgb(greenOutsideGamut, "LST001");
var a = HueColorConverter.XYToRgb(gamutGreen, CIE1931Gamut.ForModel("LST001"));
var b = HueColorConverter.XYToRgb(greenOutsideGamut, CIE1931Gamut.ForModel("LST001"));

// Points should be equal, since the green outside the gamut should
// be adjusted the the nearest green in-gamut.
Expand All @@ -76,7 +77,7 @@ public void CompareColorConversionWithReference()
var referenceXy = ReferenceColorConverter.XyFromColor(red, green, blue);

// LCT001 uses Gamut B, which is the gamut used in the reference implementation.
var actualXy = HueColorConverter.RgbToXY(new RGBColor(red, green, blue), "LCT001");
var actualXy = HueColorConverter.RgbToXY(new RGBColor(red, green, blue), CIE1931Gamut.ForModel("LCT001"));

AssertAreEqual(referenceXy, actualXy, 0.0001);
}
Expand Down Expand Up @@ -115,8 +116,8 @@ public void ColorConversionRoundtripInsideGamut()
|| !ReferenceColorConverter.CheckPointInLampsReach(originalXy)
|| !CIE1931Gamut.PhilipsWideGamut.Contains(originalXy));

RGBColor rgb = HueColorConverter.XYToRgb(originalXy, "LCT001");
var xy = HueColorConverter.RgbToXY(rgb, "LCT001");
RGBColor rgb = HueColorConverter.XYToRgb(originalXy, CIE1931Gamut.ForModel("LCT001"));
var xy = HueColorConverter.RgbToXY(rgb, CIE1931Gamut.ForModel("LCT001"));

AssertAreEqual(originalXy, xy, 0.0001);
}
Expand All @@ -139,8 +140,8 @@ public void ColorConversionRoundtripAllPoints()
}
while (originalXy.x + originalXy.y >= 1.0);

RGBColor rgb = HueColorConverter.XYToRgb(originalXy, "LCT001");
var xy = HueColorConverter.RgbToXY(rgb, "LCT001");
RGBColor rgb = HueColorConverter.XYToRgb(originalXy, CIE1931Gamut.ForModel("LCT001"));
var xy = HueColorConverter.RgbToXY(rgb, CIE1931Gamut.ForModel("LCT001"));

// We expect a point that is both inside the lamp's gamut and the "wide gamut"
// used for XYZ->RGB and RGB->XYZ conversion.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Q42.HueApi.ColorConverters.OriginalWithModel;
using Q42.HueApi.Models.Gamut;
using Q42.HueApi.ColorConverters.Gamut;

namespace Q42.HueApi.ColorConverters.Tests
{
Expand All @@ -32,7 +33,7 @@ private Bitmap DrawBitmap(string model)
for (int y = 0; y < dimension; y++)
{
CIE1931Point point = new CIE1931Point(x / (dimension * 1.0), y / (dimension * 1.0));
var rgb = HueColorConverter.XYToRgb(point, model);
var rgb = HueColorConverter.XYToRgb(point, CIE1931Gamut.ForModel(model));

Color c;
if (point.x + point.y > 1.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
<Compile Include="HSBTest\HSBTests.cs" />
<Compile Include="HSBTest\StateExtensionsTests.cs" />
<Compile Include="HueColorConverterTests.cs" />
<Compile Include="OriginalWithModel\ColorConverterTests-Arrays.cs" />
<Compile Include="OriginalWithModel\ColorConverterTests.cs" />
<Compile Include="Gamut\ColorConverterTests-Arrays.cs" />
<Compile Include="Gamut\ColorConverterTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
using System;
using Q42.HueApi.Models.Gamut;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q42.HueApi.ColorConverters.OriginalWithModel
namespace Q42.HueApi.ColorConverters.Gamut
{
public static class LightCommandExtensions
{
public static LightCommand SetColor(this LightCommand lightCommand, RGBColor color, string model = "LCT001")
public static LightCommand SetColor(this LightCommand lightCommand, RGBColor color, CIE1931Gamut? gamut)
{
if (lightCommand == null)
throw new ArgumentNullException(nameof(lightCommand));

var point = HueColorConverter.RgbToXY(color, model);
var point = HueColorConverter.RgbToXY(color, gamut);
return lightCommand.SetColor(point.x, point.y);
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/Q42.HueApi.ColorConverters/Gamut/Extensions/LightExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Q42.HueApi.Models.Gamut;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q42.HueApi.ColorConverters.Gamut
{
public static class LightExtensions
{
public static string ToHex(this Light light)
{
return light.ToHex(light.Capabilities?.Control?.ColorGamut);
}

public static string ToHex(this Light light, CIE1931Gamut? gamut)
{
return HueColorConverter.HexFromState(light.State, gamut);
}
}
}
22 changes: 22 additions & 0 deletions src/Q42.HueApi.ColorConverters/Gamut/Extensions/StateExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Q42.HueApi.Models.Gamut;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q42.HueApi.ColorConverters.Gamut
{
public static class StateExtensions
{
public static string ToHex(this State state, CIE1931Gamut? gamut)
{
return HueColorConverter.HexFromState(state, gamut);
}

public static RGBColor ToRgb(this State state, CIE1931Gamut? gamut)
{
return HueColorConverter.RgbFromState(state, gamut);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using Q42.HueApi.ColorConverters;
using Q42.HueApi.ColorConverters;
using Q42.HueApi.Models.Gamut;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q42.HueApi.ColorConverters.OriginalWithModel
namespace Q42.HueApi.ColorConverters.Gamut
{
/// <summary>
/// Used to convert colors between XY and RGB
Expand All @@ -16,7 +17,7 @@ namespace Q42.HueApi.ColorConverters.OriginalWithModel
/// </remarks>
internal static class HueColorConverter
{
public static CIE1931Point RgbToXY(RGBColor color, string model)
public static CIE1931Point RgbToXY(RGBColor color, CIE1931Gamut? gamut)
{
// Apply gamma correction. Convert non-linear RGB colour components
// to linear color intensity levels.
Expand Down Expand Up @@ -61,13 +62,10 @@ public static CIE1931Point RgbToXY(RGBColor color, string model)
xyPoint = new CIE1931Point(X / (X + Y + Z), Y / (X + Y + Z));
}

if (model != null)
if (gamut.HasValue)
{
//Check if the given XY value is within the colourreach of our lamps.
CIE1931Gamut gamut = CIE1931Gamut.ForModel(model);

// The point, adjusted it to the nearest point that is within the gamut of the lamp, if neccessary.
return gamut.NearestContainedPoint(xyPoint);
return gamut.Value.NearestContainedPoint(xyPoint);
}
return xyPoint;
}
Expand All @@ -78,9 +76,9 @@ public static CIE1931Point RgbToXY(RGBColor color, string model)
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
public static string HexFromState(State state, string model)
public static string HexFromState(State state, CIE1931Gamut? gamut)
{
var rgb = RgbFromState(state, model);
var rgb = RgbFromState(state, gamut);

return rgb.ToHex();
}
Expand All @@ -90,30 +88,28 @@ public static string HexFromState(State state, string model)
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
public static RGBColor RgbFromState(State state, string model)
public static RGBColor RgbFromState(State state, CIE1931Gamut? gamut)
{
if (state == null)
throw new ArgumentNullException(nameof(state));
if (state.On == false || state.Brightness <= 5) //Off or low brightness
return new RGBColor(0,0,0);
if (state.ColorCoordinates != null && state.ColorCoordinates.Length == 2) //Based on XY value
{
var color = XYToRgb(new CIE1931Point(state.ColorCoordinates[0], state.ColorCoordinates[1]), model);
var color = XYToRgb(new CIE1931Point(state.ColorCoordinates[0], state.ColorCoordinates[1]), gamut);
return color;
}

return new RGBColor(1, 1, 1); ;
}

public static RGBColor XYToRgb(CIE1931Point point, string model)
public static RGBColor XYToRgb(CIE1931Point point, CIE1931Gamut? gamut)
{
if (model != null)
if (gamut.HasValue)
{
CIE1931Gamut gamut = CIE1931Gamut.ForModel(model);

// If the color is outside the lamp's gamut, adjust to the nearest color
// inside the lamp's gamut.
point = gamut.NearestContainedPoint(point);
point = gamut.Value.NearestContainedPoint(point);
}

// Also adjust it to be in the Philips "Wide Gamut" if not already.
Expand Down
Loading

0 comments on commit 239fa79

Please sign in to comment.