From 2cb4bbdc835a0b95626ecb466dc15fda93f3dd1b Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 24 Feb 2019 11:50:30 +0100 Subject: [PATCH 1/8] Added tests for colors --- RGB.NET.sln | 9 + Tests/RGB.NET.Core.Tests/Color/ColorTest.cs | 395 ++++++++++++++ .../RGB.NET.Core.Tests/Color/HSVColorTest.cs | 308 +++++++++++ .../RGB.NET.Core.Tests/Color/RGBColorTest.cs | 504 ++++++++++++++++++ .../RGB.NET.Core.Tests.csproj | 19 + 5 files changed, 1235 insertions(+) create mode 100644 Tests/RGB.NET.Core.Tests/Color/ColorTest.cs create mode 100644 Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs create mode 100644 Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs create mode 100644 Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj diff --git a/RGB.NET.sln b/RGB.NET.sln index b6ea9d4..9898c32 100644 --- a/RGB.NET.sln +++ b/RGB.NET.sln @@ -39,6 +39,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Groups", "RGB.NET.G EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.WS281X", "RGB.NET.Devices.WS281X\RGB.NET.Devices.WS281X.csproj", "{0AD382DA-E999-4F74-9658-8D402EE9BF3F}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{92D7C263-D4C9-4D26-93E2-93C1F9C2CD16}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RGB.NET.Core.Tests", "Tests\RGB.NET.Core.Tests\RGB.NET.Core.Tests.csproj", "{A3FD5AD7-040A-47CA-A278-53493A25FF8A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -109,6 +113,10 @@ Global {0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU {0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU {0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Release|Any CPU.Build.0 = Release|Any CPU + {A3FD5AD7-040A-47CA-A278-53493A25FF8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3FD5AD7-040A-47CA-A278-53493A25FF8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3FD5AD7-040A-47CA-A278-53493A25FF8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3FD5AD7-040A-47CA-A278-53493A25FF8A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -129,6 +137,7 @@ Global {8725C448-818C-41F7-B23F-F97E062BF233} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F} {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F} {0AD382DA-E999-4F74-9658-8D402EE9BF3F} = {D13032C6-432E-4F43-8A32-071133C22B16} + {A3FD5AD7-040A-47CA-A278-53493A25FF8A} = {92D7C263-D4C9-4D26-93E2-93C1F9C2CD16} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7F222AD4-1F9E-4AAB-9D69-D62372D4C1BA} diff --git a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs new file mode 100644 index 0000000..8146006 --- /dev/null +++ b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs @@ -0,0 +1,395 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace RGB.NET.Core.Tests.Color +{ + [TestClass] + public class ColorTest + { + #region Basics + + [TestMethod] + public void VerifyTransparent() + { + Core.Color transparent = Core.Color.Transparent; + + Assert.AreEqual(0, transparent.A, "A is not 0"); + Assert.AreEqual(0, transparent.R, "R is not 0"); + Assert.AreEqual(0, transparent.G, "G is not 0"); + Assert.AreEqual(0, transparent.B, "B is not 0"); + } + + [TestMethod] + public void ToStringTest() + { + Core.Color color = new Core.Color(255, 120, 13, 1); + + Assert.AreEqual("[A: 255, R: 120, G: 13, B: 1]", color.ToString()); + } + + #region HashCode + + [TestMethod] + public void GetHashCodeTestEqual() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 68, 32, 255); + + Assert.AreEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualA() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(99, 68, 32, 255); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualR() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 69, 32, 255); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualG() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 68, 200, 255); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualB() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 68, 32, 0); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + #endregion + + #region Equality + + [TestMethod] + public void EqualityTestEqual() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 68, 32, 255); + + Assert.IsTrue(color1.Equals(color2), $"Equals returns false on equal colors {color1} and {color2}"); + Assert.IsTrue(color1 == color2, $"Equal-operator returns false on equal colors {color1} and {color2}"); + Assert.IsFalse(color1 != color2, $"Not-Equal-operator returns true on equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualA() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(99, 68, 32, 255); + + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualR() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 69, 32, 255); + + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualG() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 68, 200, 255); + + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualB() + { + Core.Color color1 = new Core.Color(100, 68, 32, 255); + Core.Color color2 = new Core.Color(100, 68, 32, 0); + + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } + + #endregion + + #endregion + + #region Constructors + + [TestMethod] + public void RGBByteConstructorTest() + { + Core.Color color = new Core.Color((byte)10, (byte)120, (byte)255); + + Assert.AreEqual(255, color.A, "A is not 255"); + Assert.AreEqual(10, color.R, "R is not 10"); + Assert.AreEqual(120, color.G, "G is not 120"); + Assert.AreEqual(255, color.B, "B is not 255"); + } + + [TestMethod] + public void ARGBByteConstructorTest() + { + Core.Color color = new Core.Color((byte)200, (byte)10, (byte)120, (byte)255); + + Assert.AreEqual(200, color.A, "A is not 200"); + Assert.AreEqual(10, color.R, "R is not 10"); + Assert.AreEqual(120, color.G, "G is not 120"); + Assert.AreEqual(255, color.B, "B is not 255"); + } + + [TestMethod] + public void RGBIntConstructorTest() + { + Core.Color color = new Core.Color(10, 120, 255); + + Assert.AreEqual(255, color.A, "A is not 255"); + Assert.AreEqual(10, color.R, "R is not 10"); + Assert.AreEqual(120, color.G, "G is not 120"); + Assert.AreEqual(255, color.B, "B is not 255"); + } + + [TestMethod] + public void ARGBIntConstructorTest() + { + Core.Color color = new Core.Color(200, 10, 120, 255); + + Assert.AreEqual(200, color.A, "A is not 200"); + Assert.AreEqual(10, color.R, "R is not 10"); + Assert.AreEqual(120, color.G, "G is not 120"); + Assert.AreEqual(255, color.B, "B is not 255"); + } + + [TestMethod] + public void RGBIntConstructorClampTest() + { + Core.Color color1 = new Core.Color(256, 256, 256); + + Assert.AreEqual(255, color1.A, "A is not 255"); + Assert.AreEqual(255, color1.R, "R is not 255"); + Assert.AreEqual(255, color1.G, "G is not 255"); + Assert.AreEqual(255, color1.B, "B is not 255"); + + Core.Color color2 = new Core.Color(-1, -1, -1); + + Assert.AreEqual(255, color2.A, "A is not 255"); + Assert.AreEqual(0, color2.R, "R is not 0"); + Assert.AreEqual(0, color2.G, "G is not 0"); + Assert.AreEqual(0, color2.B, "B is not 0"); + } + + [TestMethod] + public void ARGBIntConstructorClampTest() + { + Core.Color color = new Core.Color(256, 256, 256, 256); + + Assert.AreEqual(255, color.A, "A is not 255"); + Assert.AreEqual(255, color.R, "R is not 255"); + Assert.AreEqual(255, color.G, "G is not 255"); + Assert.AreEqual(255, color.B, "B is not 255"); + + Core.Color color2 = new Core.Color(-1, -1, -1, -1); + + Assert.AreEqual(0, color2.A, "A is not 0"); + Assert.AreEqual(0, color2.R, "R is not 0"); + Assert.AreEqual(0, color2.G, "G is not 0"); + Assert.AreEqual(0, color2.B, "B is not 0"); + } + + [TestMethod] + public void RGBPercentConstructorTest() + { + Core.Color color = new Core.Color(0.25341, 0.55367, 1); + + Assert.AreEqual(1, color.APercent, DoubleExtensions.TOLERANCE, "A is not 1"); + Assert.AreEqual(0.25341, color.RPercent, DoubleExtensions.TOLERANCE, "R is not 0.25341"); + Assert.AreEqual(0.55367, color.GPercent, DoubleExtensions.TOLERANCE, "G is not 0.55367"); + Assert.AreEqual(1, color.BPercent, DoubleExtensions.TOLERANCE, "B is not 1"); + } + + [TestMethod] + public void ARGBPercentConstructorTest() + { + Core.Color color = new Core.Color(0.3315, 0.25341, 0.55367, 1); + + Assert.AreEqual(0.3315, color.APercent, DoubleExtensions.TOLERANCE, "A is not 0.3315"); + Assert.AreEqual(0.25341, color.RPercent, DoubleExtensions.TOLERANCE, "R is not 0.25341"); + Assert.AreEqual(0.55367, color.GPercent, DoubleExtensions.TOLERANCE, "G is not 0.55367"); + Assert.AreEqual(1, color.BPercent, DoubleExtensions.TOLERANCE, "B is not 1"); + } + + [TestMethod] + public void RGBPercentConstructorClampTest() + { + Core.Color color1 = new Core.Color(1.1, 1.1, 1.1); + + Assert.AreEqual(1, color1.APercent, "A is not 1"); + Assert.AreEqual(1, color1.RPercent, "R is not 1"); + Assert.AreEqual(1, color1.GPercent, "G is not 1"); + Assert.AreEqual(1, color1.BPercent, "B is not 1"); + + Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0); + + Assert.AreEqual(1, color2.APercent, "A is not 1"); + Assert.AreEqual(0, color2.RPercent, "R is not 0"); + Assert.AreEqual(0, color2.GPercent, "G is not 0"); + Assert.AreEqual(0, color2.BPercent, "B is not 0"); + } + + [TestMethod] + public void ARGBPercentConstructorClampTest() + { + Core.Color color1 = new Core.Color(1.1, 1.1, 1.1, 1.1); + + Assert.AreEqual(1, color1.APercent, "A is not 1"); + Assert.AreEqual(1, color1.RPercent, "R is not 1"); + Assert.AreEqual(1, color1.GPercent, "G is not 1"); + Assert.AreEqual(1, color1.BPercent, "B is not 1"); + + Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0, -1.0); + + Assert.AreEqual(0, color2.APercent, "A is not 0"); + Assert.AreEqual(0, color2.RPercent, "R is not 0"); + Assert.AreEqual(0, color2.GPercent, "G is not 0"); + Assert.AreEqual(0, color2.BPercent, "B is not 0"); + } + + [TestMethod] + public void CloneConstructorTest() + { + Core.Color referennceColor = new Core.Color(200, 10, 120, 255); + Core.Color color = new Core.Color(referennceColor); + + Assert.AreEqual(200, color.A, "A is not 200"); + Assert.AreEqual(10, color.R, "R is not 10"); + Assert.AreEqual(120, color.G, "G is not 120"); + Assert.AreEqual(255, color.B, "B is not 255"); + } + + #endregion + + #region Conversion + + [TestMethod] + public void ColorFromComponentsTest() + { + Core.Color color = (255, 120, 13, 1); + + Assert.AreEqual(255, color.A, $"A doesn't equal the used component. ({color.A} != 255)"); + Assert.AreEqual(120, color.R, $"R doesn't equal the used component. ({color.R} != 120)"); + Assert.AreEqual(13, color.G, $"G doesn't equal the used component. ({color.G} != 13)"); + Assert.AreEqual(1, color.B, $"B doesn't equal the used component. ({color.B} != 1)"); + } + + [TestMethod] + public void DesconstructTest() + { + (byte a, byte r, byte g, byte b) = new Core.Color(255, 120, 13, 1); + + Assert.AreEqual(255, a, $"A doesn't equal the color. ({a} != 255)"); + Assert.AreEqual(120, r, $"R doesn't equal the color. ({r} != 120)"); + Assert.AreEqual(13, g, $"G doesn't equal the color. ({g} != 13)"); + Assert.AreEqual(1, b, $"B doesn't equal the color. ({b} != 1)"); + } + + [TestMethod] + public void AToPercentTest() + { + Core.Color color1 = new Core.Color(0, 0, 0, 0); + Assert.AreEqual(0, color1.APercent); + + Core.Color color2 = new Core.Color(255, 0, 0, 0); + Assert.AreEqual(1, color2.APercent); + + Core.Color color3 = new Core.Color(128, 0, 0, 0); + Assert.AreEqual(128 / 255.0, color3.APercent); + + Core.Color color4 = new Core.Color(30, 0, 0, 0); + Assert.AreEqual(30 / 255.0, color4.APercent); + + Core.Color color5 = new Core.Color(201, 0, 0, 0); + Assert.AreEqual(201 / 255.0, color5.APercent); + } + + [TestMethod] + public void RToPercentTest() + { + Core.Color color1 = new Core.Color(0, 0, 0, 0); + Assert.AreEqual(0, color1.RPercent); + + Core.Color color2 = new Core.Color(0, 255, 0, 0); + Assert.AreEqual(1, color2.RPercent); + + Core.Color color3 = new Core.Color(0, 128, 0, 0); + Assert.AreEqual(128 / 255.0, color3.RPercent); + + Core.Color color4 = new Core.Color(0, 30, 0, 0); + Assert.AreEqual(30 / 255.0, color4.RPercent); + + Core.Color color5 = new Core.Color(0, 201, 0, 0); + Assert.AreEqual(201 / 255.0, color5.RPercent); + } + + [TestMethod] + public void GToPercentTest() + { + Core.Color color1 = new Core.Color(0, 0, 0, 0); + Assert.AreEqual(0, color1.GPercent); + + Core.Color color2 = new Core.Color(0, 0, 255, 0); + Assert.AreEqual(1, color2.GPercent); + + Core.Color color3 = new Core.Color(0, 0, 128, 0); + Assert.AreEqual(128 / 255.0, color3.GPercent); + + Core.Color color4 = new Core.Color(0, 0, 30, 0); + Assert.AreEqual(30 / 255.0, color4.GPercent); + + Core.Color color5 = new Core.Color(0, 0, 201, 0); + Assert.AreEqual(201 / 255.0, color5.GPercent); + } + + [TestMethod] + public void BToPercentTest() + { + Core.Color color1 = new Core.Color(0, 0, 0, 0); + Assert.AreEqual(0, color1.BPercent); + + Core.Color color2 = new Core.Color(0, 0, 0, 255); + Assert.AreEqual(1, color2.BPercent); + + Core.Color color3 = new Core.Color(0, 0, 0, 128); + Assert.AreEqual(128 / 255.0, color3.BPercent); + + Core.Color color4 = new Core.Color(0, 0, 0, 30); + Assert.AreEqual(30 / 255.0, color4.BPercent); + + Core.Color color5 = new Core.Color(0, 0, 0, 201); + Assert.AreEqual(201 / 255.0, color5.BPercent); + } + + #endregion + } +} diff --git a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs new file mode 100644 index 0000000..6d5c9ba --- /dev/null +++ b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs @@ -0,0 +1,308 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace RGB.NET.Core.Tests.Color +{ + [TestClass] + public class HSVColorTest + { + #region Manipulation + + #region Blend + + [TestMethod] + public void BlendOpaqueTest() + { + Assert.Inconclusive(); + //Core.Color baseColor = new Core.Color(255, 0, 0); + //Core.Color blendColor = new Core.Color(0, 255, 0); + + //Assert.AreEqual(blendColor, baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendTransparentTest() + { + Assert.Inconclusive(); + //Core.Color baseColor = new Core.Color(255, 0, 0); + //Core.Color blendColor = new Core.Color(0, 0, 255, 0); + + //Assert.AreEqual(baseColor, baseColor.Blend(blendColor)); + } + + #endregion + + #region Add + + [TestMethod] + public void AddHueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.AddHue(30); + + Assert.AreEqual(Core.Color.FromHSV(210, 0.5, 0.5), result); + } + + [TestMethod] + public void AddHueWrapTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.AddHue(220); + + Assert.AreEqual(Core.Color.FromHSV(40, 0.5, 0.5), result); + } + + [TestMethod] + public void AddSaturationTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.AddSaturation(0.3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.8, 0.5), result); + } + + [TestMethod] + public void AddSaturationClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.AddSaturation(0.8); + + Assert.AreEqual(Core.Color.FromHSV(180, 1.0, 0.5), result); + } + + [TestMethod] + public void AddValueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.AddValue(0.3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.8), result); + } + + [TestMethod] + public void AddValueClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.AddValue(0.8); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 1.0), result); + } + + #endregion + + #region Subtract + + [TestMethod] + public void SubtractHueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHue(30); + + Assert.AreEqual(Core.Color.FromHSV(150, 0.5, 0.5), result); + } + + [TestMethod] + public void SubtractHueWrapTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHue(220); + + Assert.AreEqual(Core.Color.FromHSV(320, 0.5, 0.5), result); + } + + [TestMethod] + public void SubtractSaturationTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractSaturation(0.3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.2, 0.5), result); + } + + [TestMethod] + public void SubtractSaturationClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractSaturation(0.8); + + Assert.AreEqual(Core.Color.FromHSV(180, 0, 0.5), result); + } + + [TestMethod] + public void SubtractValueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractValue(0.3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.2), result); + } + + [TestMethod] + public void SubtractValueClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractValue(0.8); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0), result); + } + + #endregion + + #region Multiply + + [TestMethod] + public void MultiplyHueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyHue(1.5); + + Assert.AreEqual(Core.Color.FromHSV(270, 0.5, 0.5), result); + } + + [TestMethod] + public void MultiplyHueWrapTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyHue(3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.5), result); + } + + [TestMethod] + public void MultiplySaturationTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.2, 0.2); + Core.Color result = baseColor.MultiplySaturation(3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.6, 0.2), result); + } + + [TestMethod] + public void MultiplySaturationClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplySaturation(3); + + Assert.AreEqual(Core.Color.FromHSV(180, 1.0, 0.5), result); + } + + [TestMethod] + public void MultiplyValueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.2, 0.2); + Core.Color result = baseColor.MultiplyValue(3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.2, 0.6), result); + } + + [TestMethod] + public void MultiplyValueClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyValue(3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 1.0), result); + } + + #endregion + + #region Divide + + [TestMethod] + public void DivideHueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.DivideHue(30); + + Assert.AreEqual(Core.Color.FromHSV(6, 0.5, 0.5), result); + } + + [TestMethod] + public void DivideSaturationTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.6, 0.6); + Core.Color result = baseColor.DivideSaturation(2); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.3, 0.6), result); + } + + [TestMethod] + public void DivideValueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.6, 0.6); + Core.Color result = baseColor.DivideValue(2); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.6, 0.3), result); + } + + #endregion + + #region Set + + [TestMethod] + public void SetHueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetHue(30); + + Assert.AreEqual(Core.Color.FromHSV(30, 0.5, 0.5), result); + } + + [TestMethod] + public void SetHueWrapTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetHue(440); + + Assert.AreEqual(Core.Color.FromHSV(80, 0.5, 0.5), result); + } + + [TestMethod] + public void SetHueWrapNegativeTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetHue(-30); + + Assert.AreEqual(Core.Color.FromHSV(330, 0.5, 0.5), result); + } + + [TestMethod] + public void SetSaturationTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetSaturation(0.3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.3, 0.5), result); + } + + [TestMethod] + public void SetSaturationClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetSaturation(2); + + Assert.AreEqual(Core.Color.FromHSV(180, 1.0, 0.5), result); + } + + [TestMethod] + public void SetValueTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetValue(0.3); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.3), result); + } + + [TestMethod] + public void SetValueClampTest() + { + Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); + Core.Color result = baseColor.SetValue(2); + + Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 1.0), result); + } + + #endregion + + #endregion + } +} diff --git a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs new file mode 100644 index 0000000..f2753e7 --- /dev/null +++ b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs @@ -0,0 +1,504 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace RGB.NET.Core.Tests.Color +{ + [TestClass] + public class RGBColorTest + { + #region Manipulation + + #region Blend + + [TestMethod] + public void BlendOpaqueTest() + { + Core.Color baseColor = new Core.Color(255, 0, 0); + Core.Color blendColor = new Core.Color(0, 255, 0); + + Assert.AreEqual(blendColor, baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendTransparentTest() + { + Core.Color baseColor = new Core.Color(255, 0, 0); + Core.Color blendColor = new Core.Color(0, 0, 255, 0); + + Assert.AreEqual(baseColor, baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendUpTest() + { + Core.Color baseColor = new Core.Color(0.0, 0.0, 0.0); + Core.Color blendColor = new Core.Color(0.5, 1.0, 1.0, 1.0); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendDownTest() + { + Core.Color baseColor = new Core.Color(1.0, 1.0, 1.0); + Core.Color blendColor = new Core.Color(1.0, 0.0, 0.0, 0.0); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); + } + + #endregion + + #region Add + + [TestMethod] + public void AddRGBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.AddRGB(11, 12, 13); + + Assert.AreEqual(new Core.Color(128, 139, 140, 141), result); + } + + [TestMethod] + public void AddARGBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.AddRGB(10, 11, 12, 13); + + Assert.AreEqual(new Core.Color(138, 139, 140, 141), result); + } + + [TestMethod] + public void AddRGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.AddPercent(0.2, 0.3, 0.4); + + Assert.AreEqual(new Core.Color(0.5, 0.7, 0.8, 0.9), result); + } + + [TestMethod] + public void AddARGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.AddPercent(0.1, 0.2, 0.3, 0.4); + + Assert.AreEqual(new Core.Color(0.6, 0.7, 0.8, 0.9), result); + } + + [TestMethod] + public void AddATest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.AddA(10); + + Assert.AreEqual(new Core.Color(138, 128, 128, 128), result); + } + + [TestMethod] + public void AddAPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.AddAPercent(0.1); + + Assert.AreEqual(new Core.Color(0.6, 0.5, 0.5, 0.5), result); + } + + [TestMethod] + public void AddRTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.AddR(10); + + Assert.AreEqual(new Core.Color(128, 138, 128, 128), result); + } + + [TestMethod] + public void AddRPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.AddRPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.6, 0.5, 0.5), result); + } + + [TestMethod] + public void AddGTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.AddG(10); + + Assert.AreEqual(new Core.Color(128, 128, 138, 128), result); + } + + [TestMethod] + public void AddGPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.AddGPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.6, 0.5), result); + } + + [TestMethod] + public void AddBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.AddB(10); + + Assert.AreEqual(new Core.Color(128, 128, 128, 138), result); + } + + [TestMethod] + public void AddBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.AddBPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.6), result); + } + + #endregion + + #region Substract + + [TestMethod] + public void SubtractRGBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SubtractRGB(11, 12, 13); + + Assert.AreEqual(new Core.Color(128, 117, 116, 115), result); + } + + [TestMethod] + public void SubtractARGBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SubtractRGB(10, 11, 12, 13); + + Assert.AreEqual(new Core.Color(118, 117, 116, 115), result); + } + + [TestMethod] + public void SubtractRGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SubtractPercent(0.2, 0.3, 0.4); + + Assert.AreEqual(new Core.Color(0.5, 0.3, 0.2, 0.1), result); + } + + [TestMethod] + public void SubtractARGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SubtractPercent(0.1, 0.2, 0.3, 0.4); + + Assert.AreEqual(new Core.Color(0.4, 0.3, 0.2, 0.1), result); + } + + [TestMethod] + public void SubtractATest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SubtractA(10); + + Assert.AreEqual(new Core.Color(118, 128, 128, 128), result); + } + + [TestMethod] + public void SubtractAPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SubtractAPercent(0.1); + + Assert.AreEqual(new Core.Color(0.4, 0.5, 0.5, 0.5), result); + } + + [TestMethod] + public void SubtractRTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SubtractR(10); + + Assert.AreEqual(new Core.Color(128, 118, 128, 128), result); + } + + [TestMethod] + public void SubtractRPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SubtractRPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.4, 0.5, 0.5), result); + } + + [TestMethod] + public void SubtractGTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SubtractG(10); + + Assert.AreEqual(new Core.Color(128, 128, 118, 128), result); + } + + [TestMethod] + public void SubtractGPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SubtractGPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.4, 0.5), result); + } + + [TestMethod] + public void SubtractBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SubtractB(10); + + Assert.AreEqual(new Core.Color(128, 128, 128, 118), result); + } + + [TestMethod] + public void SubtractBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SubtractBPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.4), result); + } + + #endregion + + #region Multiply + + [TestMethod] + public void MultiplyRGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color result = baseColor.MultiplyPercent(3, 4, 5); + + Assert.AreEqual(new Core.Color(0.2, 0.6, 0.8, 1.0), result); + } + + [TestMethod] + public void MultiplyARGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color result = baseColor.MultiplyPercent(2, 3, 4, 5); + + Assert.AreEqual(new Core.Color(0.4, 0.6, 0.8, 1.0), result); + } + + [TestMethod] + public void MultiplyAPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color result = baseColor.MultiplyAPercent(3); + + Assert.AreEqual(new Core.Color(0.6, 0.2, 0.2, 0.2), result); + } + + [TestMethod] + public void MultiplyRPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color result = baseColor.MultiplyRPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.6, 0.2, 0.2), result); + } + + [TestMethod] + public void MultiplyGPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color result = baseColor.MultiplyGPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.6, 0.2), result); + } + + [TestMethod] + public void MultiplyBPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color result = baseColor.MultiplyBPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.6), result); + } + + #endregion + + #region Divide + + [TestMethod] + public void DivideRGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.6, 0.8, 1.0); + Core.Color result = baseColor.DividePercent(3, 4, 5); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); + } + + [TestMethod] + public void DivideARGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.4, 0.6, 0.8, 1.0); + Core.Color result = baseColor.DividePercent(2, 3, 4, 5); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); + } + + [TestMethod] + public void DivideAPercentTest() + { + Core.Color baseColor = new Core.Color(0.6, 0.2, 0.2, 0.2); + Core.Color result = baseColor.DivideAPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); + } + + [TestMethod] + public void DivideRPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.6, 0.2, 0.2); + Core.Color result = baseColor.DivideRPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); + } + + [TestMethod] + public void DivideGPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.6, 0.2); + Core.Color result = baseColor.DivideGPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); + } + + [TestMethod] + public void DivideBPercentTest() + { + Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.6); + Core.Color result = baseColor.DivideBPercent(3); + + Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); + } + + #endregion + + #region Set + + [TestMethod] + public void SetRGBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SetR(11).SetG(12).SetB(13); + + Assert.AreEqual(new Core.Color(128, 11, 12, 13), result); + } + + [TestMethod] + public void SetARGBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SetA(10).SetR(11).SetG(12).SetB(13); + + Assert.AreEqual(new Core.Color(10, 11, 12, 13), result); + } + + [TestMethod] + public void SetRGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SetRPercent(0.2).SetGPercent(0.3).SetBPercent(0.4); + + Assert.AreEqual(new Core.Color(0.5, 0.2, 0.3, 0.4), result); + } + + [TestMethod] + public void SetARGBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SetAPercent(0.1).SetRPercent(0.2).SetGPercent(0.3).SetBPercent(0.4); + + Assert.AreEqual(new Core.Color(0.1, 0.2, 0.3, 0.4), result); + } + + [TestMethod] + public void SetATest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SetA(10); + + Assert.AreEqual(new Core.Color(10, 128, 128, 128), result); + } + + [TestMethod] + public void SetAPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SetAPercent(0.1); + + Assert.AreEqual(new Core.Color(0.1, 0.5, 0.5, 0.5), result); + } + + [TestMethod] + public void SetRTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SetR(10); + + Assert.AreEqual(new Core.Color(128, 10, 128, 128), result); + } + + [TestMethod] + public void SetRPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SetRPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.1, 0.5, 0.5), result); + } + + [TestMethod] + public void SetGTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SetG(10); + + Assert.AreEqual(new Core.Color(128, 128, 10, 128), result); + } + + [TestMethod] + public void SetGPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SetGPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.1, 0.5), result); + } + + [TestMethod] + public void SetBTest() + { + Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color result = baseColor.SetB(10); + + Assert.AreEqual(new Core.Color(128, 128, 128, 10), result); + } + + [TestMethod] + public void SetBPercentTest() + { + Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color result = baseColor.SetBPercent(0.1); + + Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.1), result); + } + + #endregion + + #endregion + } +} diff --git a/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj b/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj new file mode 100644 index 0000000..49bf8e9 --- /dev/null +++ b/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + From e70c1c6bb006a1471784bdbec3160019c3cadcdd Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 24 Feb 2019 11:50:49 +0100 Subject: [PATCH 2/8] Removed equals-check in percentage->byte conversion --- RGB.NET.Core/Extensions/MathExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RGB.NET.Core/Extensions/MathExtensions.cs b/RGB.NET.Core/Extensions/MathExtensions.cs index 415a53c..397d297 100644 --- a/RGB.NET.Core/Extensions/MathExtensions.cs +++ b/RGB.NET.Core/Extensions/MathExtensions.cs @@ -68,16 +68,16 @@ namespace RGB.NET.Core return value; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte GetByteValueFromPercentage(this double percentage) { if (double.IsNaN(percentage)) return 0; percentage = percentage.Clamp(0, 1.0); - return (byte)(percentage.Equals(1.0) ? 255 : percentage * 256.0); + return (byte)(percentage >= 1.0 ? 255 : percentage * 256.0); } - + #endregion } } From c1e2af6fbbeeea81c0388cb6b16a8cae44e13c1f Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 24 Feb 2019 17:53:04 +0100 Subject: [PATCH 3/8] Refactored color --- RGB.NET.Brushes/Gradients/RainbowGradient.cs | 8 +- RGB.NET.Core/Brushes/AbstractBrush.cs | 2 +- RGB.NET.Core/Color/Color.cs | 334 +++++ RGB.NET.Core/Color/HSVColor.cs | 203 +++ RGB.NET.Core/Color/RGBColor.cs | 232 ++++ RGB.NET.Core/Extensions/MathExtensions.cs | 22 +- RGB.NET.Core/Leds/Color.cs | 1124 ----------------- RGB.NET.Core/RGB.NET.Core.csproj.DotSettings | 1 + RGB.NET.Decorators/Brush/FlashDecorator.cs | 2 +- .../Generic/LimitedColorUpdateQueue.cs | 14 +- .../Client/SoIPClientRGBDevice.cs | 2 +- .../Server/SoIPServerRGBDevice.cs | 2 +- .../Server/SoIPServerUpdateQueue.cs | 2 +- .../BitwizardWS2812USBUpdateQueue.cs | 2 +- .../RGB.NET.Core.Tests/Color/HSVColorTest.cs | 196 ++- .../RGB.NET.Core.Tests/Color/RGBColorTest.cs | 144 +-- 16 files changed, 929 insertions(+), 1361 deletions(-) create mode 100644 RGB.NET.Core/Color/Color.cs create mode 100644 RGB.NET.Core/Color/HSVColor.cs create mode 100644 RGB.NET.Core/Color/RGBColor.cs delete mode 100644 RGB.NET.Core/Leds/Color.cs diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Brushes/Gradients/RainbowGradient.cs index b99a87a..01946d0 100644 --- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs +++ b/RGB.NET.Brushes/Gradients/RainbowGradient.cs @@ -73,10 +73,8 @@ namespace RGB.NET.Brushes.Gradients public Color GetColor(double offset) { double range = EndHue - StartHue; - double hue = (StartHue + (range * offset)) % 360f; - if (hue < 0) - hue += 360; - return Color.FromHSV(hue, 1, 1); + double hue = StartHue + (range * offset); + return HSVColor.Create(hue, 1, 1); } /// @@ -87,7 +85,7 @@ namespace RGB.NET.Brushes.Gradients StartHue += offset; EndHue += offset; - + while ((StartHue > 360) && (EndHue > 360)) { StartHue -= 360; diff --git a/RGB.NET.Core/Brushes/AbstractBrush.cs b/RGB.NET.Core/Brushes/AbstractBrush.cs index 716cc4a..0c6591a 100644 --- a/RGB.NET.Core/Brushes/AbstractBrush.cs +++ b/RGB.NET.Core/Brushes/AbstractBrush.cs @@ -115,7 +115,7 @@ namespace RGB.NET.Core // Since we use HSV to calculate there is no way to make a color 'brighter' than 100% // Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness' // THIS IS NOT A HSB CALCULATION!!! - return color.MultiplyValue(Brightness.Clamp(0, 1)) + return color.MultiplyHSV(value: Brightness.Clamp(0, 1)) .MultiplyA(Opacity.Clamp(0, 1)); } diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs new file mode 100644 index 0000000..3c0667e --- /dev/null +++ b/RGB.NET.Core/Color/Color.cs @@ -0,0 +1,334 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMethodReturnValue.Global + +using System; +using System.Diagnostics; + +namespace RGB.NET.Core +{ + /// + /// + /// Represents an ARGB (alpha, red, green, blue) color. + /// + [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] + public struct Color + { + #region Constants + + /// + /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0] + /// + public static Color Transparent => new Color(0, 0, 0, 0); + + #endregion + + #region Properties & Fields + + /// + /// Gets the alpha component value of this as byte in the range [0..255]. + /// + public byte A { get; } + + /// + /// Gets the alpha component value of this as percentage in the range [0..1]. + /// + public double APercent { get; } + + /// + /// Gets the red component value of this as byte in the range [0..255]. + /// + public byte R { get; } + + /// + /// Gets the red component value of this as percentage in the range [0..1]. + /// + public double RPercent { get; } + + /// + /// Gets the green component value of this as byte in the range [0..255]. + /// + public byte G { get; } + + /// + /// Gets the green component value of this as percentage in the range [0..1]. + /// + public double GPercent { get; } + + /// + /// Gets the blue component value of this as byte in the range [0..255]. + /// + public byte B { get; } + + /// + /// Gets the blue component value of this as percentage in the range [0..1]. + /// + public double BPercent { get; } + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the struct using RGB-Values. + /// Alpha defaults to 255. + /// + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(byte r, byte g, byte b) + : this(byte.MaxValue, r, g, b) + { } + + /// + /// + /// Initializes a new instance of the struct using RGB-Values. + /// Alpha defaults to 255. + /// + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(int r, int g, int b) + : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) + { } + + /// + /// Initializes a new instance of the struct using ARGB values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(byte a, byte r, byte g, byte b) + : this(a, r, g, b, a.GetPercentageFromByteValue(), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) + { } + + /// + /// Initializes a new instance of the struct using ARGB values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(int a, int r, int g, int b) + : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) + { } + + /// + /// Initializes a new instance of the struct using RGB-percent values. + /// Alpha defaults to 1.0. + /// + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(double r, double g, double b) + : this(1.0, r, g, b) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(double a, byte r, byte g, byte b) + : this(a.GetByteValueFromPercentage(), r, g, b, + a.Clamp(0, 1), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(double a, int r, int g, int b) + : this(a, (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(int a, double r, double g, double b) + : this((byte)a.Clamp(0, byte.MaxValue), r, g, b) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(byte a, double r, double g, double b) + : this(a, r.GetByteValueFromPercentage(), g.GetByteValueFromPercentage(), b.GetByteValueFromPercentage(), + a.GetPercentageFromByteValue(), r.Clamp(0, 1), g.Clamp(0, 1), b.Clamp(0, 1)) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(double a, double r, double g, double b) + : this(a.GetByteValueFromPercentage(), r.GetByteValueFromPercentage(), g.GetByteValueFromPercentage(), b.GetByteValueFromPercentage(), + a.Clamp(0, 1), r.Clamp(0, 1), g.Clamp(0, 1), b.Clamp(0, 1)) + { } + + /// + /// + /// Initializes a new instance of the struct by cloning a existing . + /// + /// The the values are copied from. + public Color(Color color) + : this(color.APercent, color.RPercent, color.GPercent, color.BPercent) + { } + + private Color(byte a, byte r, byte g, byte b, double aP, double rP, double gP, double bP) + { + this.A = a; + this.R = r; + this.G = g; + this.B = b; + + this.APercent = aP; + this.RPercent = rP; + this.GPercent = gP; + this.BPercent = bP; + } + + #endregion + + #region Methods + + /// + /// Converts the individual byte values of this to a human-readable string. + /// + /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". + public override string ToString() => $"[A: {A}, R: {R}, G: {G}, B: {B}]"; + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object obj) + { + if (!(obj is Color)) return false; + + (byte a, byte r, byte g, byte b) = (Color)obj; + return (a == A) && (r == R) && (g == G) && (b == B); + } + + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public override int GetHashCode() + { + unchecked + { + int hashCode = APercent.GetHashCode(); + hashCode = (hashCode * 397) ^ RPercent.GetHashCode(); + hashCode = (hashCode * 397) ^ GPercent.GetHashCode(); + hashCode = (hashCode * 397) ^ BPercent.GetHashCode(); + return hashCode; + } + } + + #region Deconstruction + + /// + /// Deconstructs the Color into it's ARGB-components. + /// + /// The alpha component of this color. + /// The red component of this color. + /// The green component of this color. + /// The blue component of this color. + public void Deconstruct(out byte a, out byte r, out byte g, out byte b) + { + a = A; + r = R; + g = G; + b = B; + } + + #endregion + + #region Manipulation + + /// + /// Blends a over this color. + /// + /// The to blend. + public Color Blend(Color color) + { + if (color.A == 0) return this; + + if (color.A == 255) + return color; + + double resultA = (1.0 - ((1.0 - color.APercent) * (1.0 - APercent))); + double resultR = (((color.RPercent * color.APercent) / resultA) + ((RPercent * APercent * (1.0 - color.APercent)) / resultA)); + double resultG = (((color.GPercent * color.APercent) / resultA) + ((GPercent * APercent * (1.0 - color.APercent)) / resultA)); + double resultB = (((color.BPercent * color.APercent) / resultA) + ((BPercent * APercent * (1.0 - color.APercent)) / resultA)); + + return new Color(resultA, resultR, resultG, resultB); + } + + #endregion + + #endregion + + #region Operators + + /// + /// Blends the provided colors as if would've been called on . + /// + /// The base color. + /// The color to blend. + /// The blended color. + public static Color operator +(Color color1, Color color2) => color1.Blend(color2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(Color color1, Color color2) => color1.Equals(color2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(Color color1, Color color2) => !(color1 == color2); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b); + + /// + /// Converts a of HSV-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((double hue, double saturation, double value) components) => new Color(components.hue, components.saturation, components.value); + + #endregion + } +} diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs new file mode 100644 index 0000000..e632e6c --- /dev/null +++ b/RGB.NET.Core/Color/HSVColor.cs @@ -0,0 +1,203 @@ +using System; + +namespace RGB.NET.Core +{ + public static class HSVColor + { + #region Getter + + public static double GetHue(this Color color) => color.GetHSV().hue; + + public static double GetSaturation(this Color color) => color.GetHSV().saturation; + + public static double GetValue(this Color color) => color.GetHSV().value; + + public static (double hue, double saturation, double value) GetHSV(this Color color) + => CaclulateHSVFromRGB(color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #region Manipulation + + /// + /// Adds the given HSV values to this color. + /// + /// The hue value to add. + /// The saturation value to add. + /// The value value to add. + /// The new color after the modification. + public static Color AddHSV(this Color color, double hue = 0, double saturation = 0, double value = 0) + { + (double cHue, double cSaturation, double cValue) = color.GetHSV(); + return Create(color.APercent, cHue + hue, cSaturation + saturation, cValue + value); + } + + /// + /// Subtracts the given HSV values to this color. + /// + /// The hue value to subtract. + /// The saturation value to subtract. + /// The value value to subtract. + /// The new color after the modification. + public static Color SubtractHSV(this Color color, double hue = 0, double saturation = 0, double value = 0) + { + (double cHue, double cSaturation, double cValue) = color.GetHSV(); + return Create(color.APercent, cHue - hue, cSaturation - saturation, cValue - value); + } + + /// + /// Multiplies the given HSV values to this color. + /// + /// The hue value to multiply. + /// The saturation value to multiply. + /// The value value to multiply. + /// The new color after the modification. + public static Color MultiplyHSV(this Color color, double hue = 1, double saturation = 1, double value = 1) + { + (double cHue, double cSaturation, double cValue) = color.GetHSV(); + return Create(color.APercent, cHue * hue, cSaturation * saturation, cValue * value); + } + + + /// + /// Divides the given HSV values to this color. + /// + /// The hue value to divide. + /// The saturation value to divide. + /// The value value to divide. + /// The new color after the modification. + public static Color DivideHSV(this Color color, double hue = 1, double saturation = 1, double value = 1) + { + (double cHue, double cSaturation, double cValue) = color.GetHSV(); + return Create(color.APercent, cHue / hue, cSaturation / saturation, cValue / value); + } + + /// + /// Sets the given hue value of this color. + /// + /// The hue value to set. + /// The saturation value to set. + /// The value value to set. + /// The new color after the modification. + public static Color SetHSV(this Color color, double? hue = null, double? saturation = null, double? value = null) + { + (double cHue, double cSaturation, double cValue) = color.GetHSV(); + return Create(color.APercent, hue ?? cHue, saturation ?? cSaturation, value ?? cValue); + } + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using HSV-Values. + /// + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(double hue, double saturation, double value) + => Create(1.0, hue, saturation, value); + + /// + /// Creates a new instance of the struct using AHSV-Values. + /// + /// The alpha component value of this . + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(byte a, double hue, double saturation, double value) + => Create((double)a / byte.MaxValue, hue, saturation, value); + + /// + /// Creates a new instance of the struct using AHSV-Values. + /// + /// The alpha component value of this . + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(int a, double hue, double saturation, double value) + => Create((double)a / byte.MaxValue, hue, saturation, value); + + /// + /// Creates a new instance of the struct using AHSV-Values. + /// + /// The alpha component value of this . + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(double a, double hue, double saturation, double value) + { + (double r, double g, double b) = CalculateRGBFromHSV(hue, saturation, value); + return new Color(a, r, g, b); + } + + #endregion + + #region Helper + + private static (double h, double s, double v) CaclulateHSVFromRGB(double r, double g, double b) + { + if ((r == g) && (g == b)) return (0, 0, r); + + double min = Math.Min(Math.Min(r, g), b); + double max = Math.Max(Math.Max(r, g), b); + + double hue; + if (max == min) + hue = 0; + else if (max == r) // r is max + hue = (g - b) / (max - min); + else if (max == g) // g is max + hue = 2.0 + ((b - r) / (max - min)); + else // b is max + hue = 4.0 + ((r - g) / (max - min)); + + hue = hue * 60.0; + hue = hue.Wrap(0, 360); + + double saturation = (max == 0) ? 0 : 1.0 - (min / max); + double value = Math.Max(r, Math.Max(g, b)); + + return (hue, saturation, value); + } + + private static (double r, double g, double b) CalculateRGBFromHSV(double h, double s, double v) + { + h = h.Wrap(0, 360); + s = s.Clamp(0, 1); + v = v.Clamp(0, 1); + + if (s <= 0.0) + return (v, v, v); + + double hh = h / 60.0; + int i = (int)hh; + double ff = hh - i; + double p = v * (1.0 - s); + double q = v * (1.0 - (s * ff)); + double t = v * (1.0 - (s * (1.0 - ff))); + + switch (i) + { + case 0: + return (v, t, p); + case 1: + return (q, v, p); + case 2: + return (p, v, t); + case 3: + return (p, q, v); + case 4: + return (t, p, v); + default: + return (v, p, q); + } + } + + #endregion + } +} diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs new file mode 100644 index 0000000..fa26417 --- /dev/null +++ b/RGB.NET.Core/Color/RGBColor.cs @@ -0,0 +1,232 @@ +using System; + +namespace RGB.NET.Core +{ + public static class RGBColor + { + #region Getter + + public static (double r, double g, double b) GetRGBPercent(this Color color) + => (color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #region Manipulation + + #region Add + + /// + /// Adds the given RGB values to this color. + /// + /// The red value to add. + /// The green value to add. + /// The blue value to add. + /// The new color after the modification. + public static Color AddRGB(this Color color, int r = 0, int g = 0, int b = 0) + => new Color(color.APercent, color.R + r, color.G + g, color.B + b); + + /// + /// Adds the given RGB-percent values to this color. + /// + /// The red value to add. + /// The green value to add. + /// The blue value to add. + /// The new color after the modification. + public static Color AddRGB(this Color color, double r = 0, double g = 0, double b = 0) + => new Color(color.APercent, color.RPercent + r, color.GPercent + g, color.BPercent + b); + + /// + /// Adds the given alpha value to this color. + /// + /// The alpha value to add. + /// The new color after the modification. + public static Color AddA(this Color color, int a) + => new Color(color.A + a, color.RPercent, color.GPercent, color.BPercent); + + /// + /// Adds the given alpha-percent value to this color. + /// + /// The alpha value to add. + /// The new color after the modification. + public static Color AddA(this Color color, double a) + => new Color(color.APercent + a, color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #region Subtract + + /// + /// Subtracts the given RGB values to this color. + /// + /// The red value to subtract. + /// The green value to subtract. + /// The blue value to subtract. + /// The new color after the modification. + public static Color SubtractRGB(this Color color, int r = 0, int g = 0, int b = 0) + => new Color(color.APercent, color.R - r, color.G - g, color.B - b); + + /// + /// Subtracts the given RGB values to this color. + /// + /// The red value to subtract. + /// The green value to subtract. + /// The blue value to subtract. + /// The new color after the modification. + public static Color SubtractRGB(this Color color, double r = 0, double g = 0, double b = 0) + => new Color(color.APercent, color.RPercent - r, color.GPercent - g, color.BPercent - b); + + /// + /// Subtracts the given alpha value to this color. + /// + /// The alpha value to subtract. + /// The new color after the modification. + public static Color SubtractA(this Color color, int a) + => new Color(color.A - a, color.RPercent, color.GPercent, color.BPercent); + + /// + /// Subtracts the given alpha-percent value to this color. + /// + /// The alpha value to subtract. + /// The new color after the modification. + public static Color SubtractA(this Color color, double aPercent) + => new Color(color.APercent - aPercent, color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #region Multiply + + /// + /// Multiplies the given RGB values to this color. + /// + /// The red value to multiply. + /// The green value to multiply. + /// The blue value to multiply. + /// The new color after the modification. + public static Color MultiplyRGB(this Color color, double r = 1, double g = 1, double b = 1) + => new Color(color.APercent, color.RPercent * r, color.GPercent * g, color.BPercent * b); + + /// + /// Multiplies the given alpha value to this color. + /// + /// The alpha value to multiply. + /// The new color after the modification. + public static Color MultiplyA(this Color color, double a) + => new Color(color.APercent * a, color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #region Divide + + /// + /// Divides the given RGB values to this color. + /// + /// The red value to divide. + /// The green value to divide. + /// The blue value to divide. + /// The new color after the modification. + public static Color DivideRGB(this Color color, double r = 1, double g = 1, double b = 1) + => new Color(color.APercent, color.RPercent / r, color.GPercent / g, color.BPercent / b); + + /// + /// Divides the given alpha value to this color. + /// + /// The alpha value to divide. + /// The new color after the modification. + public static Color DivideA(this Color color, double a) + => new Color(color.APercent / a, color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #region Set + + /// + /// Sets the given RGB value of this color. + /// + /// The red value to set. + /// The green value to set. + /// The blue value to set. + /// The new color after the modification. + public static Color SetRGB(this Color color, byte? r = null, byte? g = null, byte? b = null) + => new Color(color.APercent, r ?? color.R, g ?? color.G, b ?? color.B); + + /// + /// Sets the given RGB value of this color. + /// + /// The red value to set. + /// The green value to set. + /// The blue value to set. + /// The new color after the modification. + public static Color SetRGB(this Color color, int? r = null, int? g = null, int? b = null) + => new Color(color.APercent, r ?? color.R, g ?? color.G, b ?? color.B); + + /// + /// Sets the given RGB value of this color. + /// + /// The red value to set. + /// The green value to set. + /// The blue value to set. + /// The new color after the modification. + public static Color SetRGB(this Color color, double? r = null, double? g = null, double? b = null) + => new Color(color.APercent, r ?? color.RPercent, g ?? color.GPercent, b ?? color.BPercent); + + /// + /// Sets the given alpha value of this color. + /// + /// The alpha value to set. + /// The new color after the modification. + public static Color SetA(this Color color, int a) => new Color(a, color.RPercent, color.GPercent, color.BPercent); + + /// + /// Sets the given alpha value of this color. + /// + /// The alpha value to set. + /// The new color after the modification. + public static Color SetA(this Color color, double a) => new Color(a, color.RPercent, color.GPercent, color.BPercent); + + #endregion + + #endregion + + #region Conversion + + /// + /// Gets the current color as a RGB-HEX-string. + /// + /// The RGB-HEX-string. + public static string AsRGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.R, color.G, color.B); + + /// + /// Gets the current color as a ARGB-HEX-string. + /// + /// The ARGB-HEX-string. + public static string AsARGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.A, color.R, color.G, color.B); + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using a HEX-string. + /// + /// The HEX-representation of the color. + /// The color created from the HEX-string. + public static Color FromHexString(string hexString) + { + if ((hexString == null) || (hexString.Length < 6)) + throw new ArgumentException("Invalid hex string", nameof(hexString)); + + if (hexString[0] == '#') + hexString = hexString.Substring(1); + + byte[] data = ConversionHelper.HexToBytes(hexString); + if (data.Length == 3) + return new Color(data[0], data[1], data[2]); + if (data.Length == 4) + return new Color(data[0], data[1], data[2], data[3]); + + throw new ArgumentException("Invalid hex string", nameof(hexString)); + } + + #endregion + } +} diff --git a/RGB.NET.Core/Extensions/MathExtensions.cs b/RGB.NET.Core/Extensions/MathExtensions.cs index 397d297..0a9fb88 100644 --- a/RGB.NET.Core/Extensions/MathExtensions.cs +++ b/RGB.NET.Core/Extensions/MathExtensions.cs @@ -36,7 +36,14 @@ namespace RGB.NET.Core /// The higher value of the range the value is clamped to. /// The clamped value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Clamp(this double value, double min, double max) => Math.Max(min, Math.Min(max, value)); + public static double Clamp(this double value, double min, double max) + { + // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10% + if (value < min) return min; + if (value > max) return max; + return value; + // ReSharper restore ConvertIfStatementToReturnStatement + } /// /// Clamps the provided value to be bigger or equal min and smaller or equal max. @@ -46,7 +53,14 @@ namespace RGB.NET.Core /// The higher value of the range the value is clamped to. /// The clamped value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Clamp(this int value, int min, int max) => Math.Max(min, Math.Min(max, value)); + public static int Clamp(this int value, int min, int max) + { + // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10% + if (value < min) return min; + if (value > max) return max; + return value; + // ReSharper restore ConvertIfStatementToReturnStatement + } /// /// Enforces the provided value to be in the specified range by wrapping it around the edges if it exceeds them. @@ -78,6 +92,10 @@ namespace RGB.NET.Core return (byte)(percentage >= 1.0 ? 255 : percentage * 256.0); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double GetPercentageFromByteValue(this byte value) + => ((double)value) / byte.MaxValue; + #endregion } } diff --git a/RGB.NET.Core/Leds/Color.cs b/RGB.NET.Core/Leds/Color.cs deleted file mode 100644 index cc2208d..0000000 --- a/RGB.NET.Core/Leds/Color.cs +++ /dev/null @@ -1,1124 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global -// ReSharper disable UnusedMethodReturnValue.Global - -using System; -using System.Diagnostics; - -namespace RGB.NET.Core -{ - /// - /// - /// Represents an ARGB (alpha, red, green, blue) color. - /// - [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]")] - public struct Color - { - #region Constants - - /// - /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0] - /// - public static Color Transparent => new Color(0, 0, 0, 0); - - #endregion - - #region Properties & Fields - - #region RGB - - /// - /// Gets the alpha component value of this as byte in the range [0..255]. - /// - public byte A { get; } - - /// - /// Gets the alpha component value of this as percentage in the range [0..1]. - /// - public double APercent => A / (double)byte.MaxValue; - - /// - /// Gets the red component value of this as byte in the range [0..255]. - /// - public byte R { get; } - - /// - /// Gets the red component value of this as percentage in the range [0..1]. - /// - public double RPercent => R / (double)byte.MaxValue; - - /// - /// Gets the green component value of this as byte in the range [0..255]. - /// - public byte G { get; } - - /// - /// Gets the green component value of this as percentage in the range [0..1]. - /// - public double GPercent => G / (double)byte.MaxValue; - - /// - /// Gets the blue component value of this as byte in the range [0..255]. - /// - public byte B { get; } - - /// - /// Gets the blue component value of this as percentage in the range [0..1]. - /// - public double BPercent => B / (double)byte.MaxValue; - - #endregion - - #region HSV - - /// - /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360]. - /// - public double Hue { get; } - - /// - /// Gets the saturation component value (HSV-color space) of this as degree in the range [0..1]. - /// - public double Saturation { get; } - - /// - /// Gets the value component value (HSV-color space) of this as degree in the range [0..1]. - /// - public double Value { get; } - - #endregion - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the struct using RGB-Values. - /// Alpha defaults to 255. - /// - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(byte r, byte g, byte b) - : this(byte.MaxValue, r, g, b) - { } - - /// - /// - /// Initializes a new instance of the struct using RGB-Values. - /// Alpha defaults to 255. - /// - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(int r, int g, int b) - : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) - { } - - /// - /// Initializes a new instance of the struct using ARGB values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(byte a, byte r, byte g, byte b) - { - this.A = a; - this.R = r; - this.G = g; - this.B = b; - - (double h, double s, double v) = CaclulateHSVFromRGB(r, g, b); - Hue = h; - Saturation = s; - Value = v; - } - - /// - /// Initializes a new instance of the struct using ARGB values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(int a, int r, int g, int b) - : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) - { } - - /// - /// Initializes a new instance of the struct using RGB-percent values. - /// - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(double r, double g, double b) - : this(byte.MaxValue, - r.GetByteValueFromPercentage(), - g.GetByteValueFromPercentage(), - b.GetByteValueFromPercentage()) - { } - - /// - /// Initializes a new instance of the struct using ARGB-percent values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(double a, double r, double g, double b) - : this(a.GetByteValueFromPercentage(), - r.GetByteValueFromPercentage(), - g.GetByteValueFromPercentage(), - b.GetByteValueFromPercentage()) - { } - - /// - /// - /// Initializes a new instance of the struct by cloning a existing . - /// - /// The the values are copied from. - public Color(Color color) - : this(color.A, color.R, color.G, color.B) { } - - #endregion - - #region Methods - - #region Factory - - /// - /// Creates a new instance of the struct using HSV-Values. - /// - /// The hue component value of this . - /// The saturation component value of this . - /// The value component value of this . - /// The color created from the values. - public static Color FromHSV(double hue, double saturation, double value) - { - (byte r, byte g, byte b) = CalculateRGBFromHSV(hue, saturation, value); - return new Color(r, g, b); - } - - /// - /// Creates a new instance of the struct using AHSV-Values. - /// - /// The alpha component value of this . - /// The hue component value of this . - /// The saturation component value of this . - /// The value component value of this . - /// The color created from the values. - public static Color FromHSV(int a, double hue, double saturation, double value) - { - (byte r, byte g, byte b) = CalculateRGBFromHSV(hue, saturation, value); - return new Color(a, r, g, b); - } - - /// - /// Creates a new instance of the struct using a HEX-string. - /// - /// The HEX-representation of the color. - /// The color created from the HEX-string. - public static Color FromHexString(string hexString) - { - if ((hexString == null) || (hexString.Length < 6)) - throw new ArgumentException("Invalid hex string", nameof(hexString)); - - if (hexString[0] == '#') - hexString = hexString.Substring(1); - - byte[] data = ConversionHelper.HexToBytes(hexString); - if (data.Length == 3) - return new Color(data[0], data[1], data[2]); - if (data.Length == 4) - return new Color(data[0], data[1], data[2], data[3]); - - throw new ArgumentException("Invalid hex string", nameof(hexString)); - } - - #endregion - - private static (double h, double s, double v) CaclulateHSVFromRGB(byte r, byte g, byte b) - { - if ((r == g) && (g == b)) return (0, 0, r / 255.0); - - int min = Math.Min(Math.Min(r, g), b); - int max = Math.Max(Math.Max(r, g), b); - - double hue; - if (max == min) - hue = 0; - else if (max == r) // r is max - hue = (g - b) / (double)(max - min); - else if (max == g) // g is max - hue = 2.0 + ((b - r) / (double)(max - min)); - else // b is max - hue = 4.0 + ((r - g) / (double)(max - min)); - - hue = hue * 60.0; - if (hue < 0.0) - hue += 360.0; - - double saturation = (max == 0) ? 0 : 1.0 - (min / (double)max); - double value = Math.Max(r, Math.Max(g, b)) / 255.0; - - return (hue, saturation, value); - } - - private static (byte r, byte g, byte b) CalculateRGBFromHSV(double h, double s, double v) - { - h = h.Wrap(0, 360); - s = s.Clamp(0, 1); - v = v.Clamp(0, 1); - - if (s <= 0.0) - { - byte val = v.GetByteValueFromPercentage(); - return (val, val, val); - } - - double hh = h / 60.0; - int i = (int)hh; - double ff = hh - i; - double p = v * (1.0 - s); - double q = v * (1.0 - (s * ff)); - double t = v * (1.0 - (s * (1.0 - ff))); - - switch (i) - { - case 0: - return (v.GetByteValueFromPercentage(), - t.GetByteValueFromPercentage(), - p.GetByteValueFromPercentage()); - case 1: - return (q.GetByteValueFromPercentage(), - v.GetByteValueFromPercentage(), - p.GetByteValueFromPercentage()); - case 2: - return (p.GetByteValueFromPercentage(), - v.GetByteValueFromPercentage(), - t.GetByteValueFromPercentage()); - case 3: - return (p.GetByteValueFromPercentage(), - q.GetByteValueFromPercentage(), - v.GetByteValueFromPercentage()); - case 4: - return (t.GetByteValueFromPercentage(), - p.GetByteValueFromPercentage(), - v.GetByteValueFromPercentage()); - default: - return (v.GetByteValueFromPercentage(), - p.GetByteValueFromPercentage(), - q.GetByteValueFromPercentage()); - } - } - - /// - /// Converts the individual byte values of this to a human-readable string. - /// - /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". - public override string ToString() => $"[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]"; - - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) - { - if (!(obj is Color)) return false; - - Color compareColor = (Color)obj; - return (compareColor.A == A) && (compareColor.R == R) && (compareColor.G == G) && (compareColor.B == B); - } - - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() - { - unchecked - { - int hashCode = A.GetHashCode(); - hashCode = (hashCode * 397) ^ R.GetHashCode(); - hashCode = (hashCode * 397) ^ G.GetHashCode(); - hashCode = (hashCode * 397) ^ B.GetHashCode(); - return hashCode; - } - } - - /// - /// Gets the current color as a RGB-HEX-string. - /// - /// The RGB-HEX-string. - public string AsRGBHexString() => ConversionHelper.ToHex(R, G, B); - - /// - /// Gets the current color as a ARGB-HEX-string. - /// - /// The ARGB-HEX-string. - public string AsARGBHexString() => ConversionHelper.ToHex(A, R, G, B); - - #region Deconstruction - - /// - /// Deconstructs the Color into it's components. - /// - /// The alpha component of this color. - /// The red component of this color. - /// The green component of this color. - /// The blue component of this color. - /// The hue component of this color. - /// The saturation component of this color. - /// The value component of this color. - public void Deconstruct(out byte a, out byte r, out byte g, out byte b, out double hue, out double saturation, out double value) - { - Deconstruct(out a, out r, out g, out b); - Deconstruct(out hue, out saturation, out value); - } - - /// - /// Deconstructs the Color into it's ARGB-components. - /// - /// The alpha component of this color. - /// The red component of this color. - /// The green component of this color. - /// The blue component of this color. - public void Deconstruct(out byte a, out byte r, out byte g, out byte b) - { - a = A; - r = R; - g = G; - b = B; - } - - /// - /// Deconstructs the Color into it's HSV-components. - /// - /// The hue component of this color. - /// The saturation component of this color. - /// The value component of this color. - public void Deconstruct(out double hue, out double saturation, out double value) - { - hue = Hue; - saturation = Saturation; - value = Value; - } - - #endregion - - #region Manipulation - - /// - /// Blends a over this color. - /// - /// The to blend. - public Color Blend(Color color) - { - if (color.A == 0) return this; - - if (color.A == 255) - return color; - - double resultA = (1.0 - ((1.0 - color.APercent) * (1.0 - APercent))); - double resultR = (((color.RPercent * color.APercent) / resultA) + ((RPercent * APercent * (1.0 - color.APercent)) / resultA)); - double resultG = (((color.GPercent * color.APercent) / resultA) + ((GPercent * APercent * (1.0 - color.APercent)) / resultA)); - double resultB = (((color.BPercent * color.APercent) / resultA) + ((BPercent * APercent * (1.0 - color.APercent)) / resultA)); - - return new Color(resultA, resultR, resultG, resultB); - } - - #region Add - - /// - /// Adds the given RGB values to this color. - /// - /// The red value to add. - /// The green value to add. - /// The blue value to add. - /// The new color after the modification. - public Color AddRGB(int r, int g, int b) => AddRGB(0, r, g, b); - - /// - /// Adds the given RGB values to this color. - /// - /// The alpha value to add. - /// The red value to add. - /// The green value to add. - /// The blue value to add. - /// The new color after the modification. - public Color AddRGB(int a, int r, int g, int b) - => new Color(A + a, R + r, G + g, B + b); - - /// - /// Adds the given RGB-percent values to this color. - /// - /// The red value to add. - /// The green value to add. - /// The blue value to add. - /// The new color after the modification. - public Color AddPercent(double rPercent, double gPercent, double bPercent) => AddPercent(0, rPercent, gPercent, bPercent); - - /// - /// Adds the given RGB-percent values to this color. - /// - /// The alpha value to add. - /// The red value to add. - /// The green value to add. - /// The blue value to add. - /// The new color after the modification. - public Color AddPercent(double aPercent, double rPercent, double gPercent, double bPercent) - => new Color(APercent + aPercent, RPercent + rPercent, GPercent + gPercent, BPercent + bPercent); - - /// - /// Adds the given HSV values to this color. - /// - /// The hue value to add. - /// The saturation value to add. - /// The value value to add. - /// The new color after the modification. - public Color AddHSV(double hue, double saturation, double value) => AddHSV(0, hue, saturation, value); - - /// - /// Adds the given HSV values to this color. - /// - /// The alpha value to add. - /// The hue value to add. - /// The saturation value to add. - /// The value value to add. - /// The new color after the modification. - public Color AddHSV(int a, double hue, double saturation, double value) - => FromHSV(A + a, Hue + hue, Saturation + saturation, Value + value); - - /// - /// Adds the given alpha value to this color. - /// - /// The alpha value to add. - /// The new color after the modification. - public Color AddA(int a) => new Color(A + a, R, G, B); - - /// - /// Adds the given alpha-percent value to this color. - /// - /// The alpha value to add. - /// The new color after the modification. - public Color AddAPercent(double aPercent) => new Color(APercent + aPercent, RPercent, GPercent, BPercent); - - /// - /// Adds the given red value to this color. - /// - /// The red value to add. - /// The new color after the modification. - public Color AddR(int r) => new Color(A, R + r, G, B); - - /// - /// Adds the given red-percent value to this color. - /// - /// The red value to add. - /// The new color after the modification. - public Color AddRPercent(double rPercent) => new Color(APercent, RPercent + rPercent, GPercent, BPercent); - - /// - /// Adds the given green value to this color. - /// - /// The green value to add. - /// The new color after the modification. - public Color AddG(int g) => new Color(A, R, G + g, B); - - /// - /// Adds the given green-percent value to this color. - /// - /// The green value to add. - /// The new color after the modification. - public Color AddGPercent(double gPercent) => new Color(APercent, RPercent, GPercent + gPercent, BPercent); - - /// - /// Adds the given blue value to this color. - /// - /// The blue value to add. - /// The new color after the modification. - public Color AddB(int b) => new Color(A, R, G, B + b); - - /// - /// Adds the given blue-percent value to this color. - /// - /// The blue value to add. - /// The new color after the modification. - public Color AddBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent + bPercent); - - /// - /// Adds the given hue value to this color. - /// - /// The hue value to add. - /// The new color after the modification. - public Color AddHue(double hue) => FromHSV(A, Hue + hue, Saturation, Value); - - /// - /// Adds the given saturation value to this color. - /// - /// The saturation value to add. - /// The new color after the modification. - public Color AddSaturation(double saturation) => FromHSV(A, Hue, Saturation + saturation, Value); - - /// - /// Adds the given value value to this color. - /// - /// The value value to add. - /// The new color after the modification. - public Color AddValue(double value) => FromHSV(A, Hue, Saturation, Value + value); - - #endregion - - #region Subtract - - /// - /// Subtracts the given RGB values to this color. - /// - /// The red value to subtract. - /// The green value to subtract. - /// The blue value to subtract. - /// The new color after the modification. - public Color SubtractRGB(int r, int g, int b) => SubtractRGB(0, r, g, b); - - /// - /// Subtracts the given RGB values to this color. - /// - /// The alpha value to subtract. - /// The red value to subtract. - /// The green value to subtract. - /// The blue value to subtract. - /// The new color after the modification. - public Color SubtractRGB(int a, int r, int g, int b) - => new Color(A - a, R - r, G - g, B - b); - - /// - /// Subtracts the given RGB-percent values to this color. - /// - /// The red value to subtract. - /// The green value to subtract. - /// The blue value to subtract. - /// The new color after the modification. - public Color SubtractPercent(double rPercent, double gPercent, double bPercent) => SubtractPercent(0, rPercent, gPercent, bPercent); - - /// - /// Subtracts the given RGB-percent values to this color. - /// - /// The alpha value to subtract. - /// The red value to subtract. - /// The green value to subtract. - /// The blue value to subtract. - /// The new color after the modification. - public Color SubtractPercent(double aPercent, double rPercent, double gPercent, double bPercent) - => new Color(APercent - aPercent, RPercent - rPercent, GPercent - gPercent, BPercent - bPercent); - - /// - /// Subtracts the given HSV values to this color. - /// - /// The hue value to subtract. - /// The saturation value to subtract. - /// The value value to subtract. - /// The new color after the modification. - public Color SubtractHSV(double hue, double saturation, double value) => SubtractHSV(0, hue, saturation, value); - - /// - /// Subtracts the given HSV values to this color. - /// - /// The alpha value to subtract. - /// The hue value to subtract. - /// The saturation value to subtract. - /// The value value to subtract. - /// The new color after the modification. - public Color SubtractHSV(int a, double hue, double saturation, double value) - => FromHSV(A - a, Hue - hue, Saturation - saturation, Value - value); - - /// - /// Subtracts the given alpha value to this color. - /// - /// The alpha value to subtract. - /// The new color after the modification. - public Color SubtractA(int a) => new Color(A - a, R, G, B); - - /// - /// Subtracts the given alpha-percent value to this color. - /// - /// The alpha value to subtract. - /// The new color after the modification. - public Color SubtractAPercent(double aPercent) => new Color(APercent - aPercent, RPercent, GPercent, BPercent); - - /// - /// Subtracts the given red value to this color. - /// - /// The red value to subtract. - /// The new color after the modification. - public Color SubtractR(int r) => new Color(A, R - r, G, B); - - /// - /// Subtracts the given red-percent value to this color. - /// - /// The red value to subtract. - /// The new color after the modification. - public Color SubtractRPercent(double rPercent) => new Color(APercent, RPercent - rPercent, GPercent, BPercent); - - /// - /// Subtracts the given green value to this color. - /// - /// The green value to subtract. - /// The new color after the modification. - public Color SubtractG(int g) => new Color(A, R, G - g, B); - - /// - /// Subtracts the given green-percent value to this color. - /// - /// The green value to subtract. - /// The new color after the modification. - public Color SubtractGPercent(double gPercent) => new Color(APercent, RPercent, GPercent - gPercent, BPercent); - - /// - /// Subtracts the given blue value to this color. - /// - /// The blue value to subtract. - /// The new color after the modification. - public Color SubtractB(int b) => new Color(A, R, G, B - b); - - /// - /// Subtracts the given blue-percent value to this color. - /// - /// The blue value to subtract. - /// The new color after the modification. - public Color SubtractBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent - bPercent); - - /// - /// Subtracts the given hue value to this color. - /// - /// The hue value to subtract. - /// The new color after the modification. - public Color SubtractHue(double hue) => FromHSV(A, Hue - hue, Saturation, Value); - - /// - /// Subtracts the given saturation value to this color. - /// - /// The saturation value to subtract. - /// The new color after the modification. - public Color SubtractSaturation(double saturation) => FromHSV(A, Hue, Saturation - saturation, Value); - - /// - /// Subtracts the given value value to this color. - /// - /// The value value to subtract. - /// The new color after the modification. - public Color SubtractValue(double value) => FromHSV(A, Hue, Saturation, Value - value); - - #endregion - - #region Multiply - - /// - /// Multiplies the given RGB values to this color. - /// - /// The red value to multiply. - /// The green value to multiply. - /// The blue value to multiply. - /// The new color after the modification. - public Color MultiplyRGB(double r, double g, double b) => MultiplyRGB(1, r, g, b); - - /// - /// Multiplies the given RGB values to this color. - /// - /// The alpha value to multiply. - /// The red value to multiply. - /// The green value to multiply. - /// The blue value to multiply. - /// The new color after the modification. - public Color MultiplyRGB(double a, double r, double g, double b) - => new Color((int)Math.Round(A * a), (int)Math.Round(R * r), (int)Math.Round(G * g), (int)Math.Round(B * b)); - - /// - /// Multiplies the given RGB-percent values to this color. - /// - /// The red value to multiply. - /// The green value to multiply. - /// The blue value to multiply. - /// The new color after the modification. - public Color MultiplyPercent(double rPercent, double gPercent, double bPercent) => MultiplyPercent(1, rPercent, gPercent, bPercent); - - /// - /// Multiplies the given RGB-percent values to this color. - /// - /// The alpha value to multiply. - /// The red value to multiply. - /// The green value to multiply. - /// The blue value to multiply. - /// The new color after the modification. - public Color MultiplyPercent(double aPercent, double rPercent, double gPercent, double bPercent) - => new Color(APercent * aPercent, RPercent * rPercent, GPercent * gPercent, BPercent * bPercent); - - /// - /// Multiplies the given HSV values to this color. - /// - /// The hue value to multiply. - /// The saturation value to multiply. - /// The value value to multiply. - /// The new color after the modification. - public Color MultiplyHSV(double hue, double saturation, double value) => MultiplyHSV(1, hue, saturation, value); - - /// - /// Multiplies the given HSV values to this color. - /// - /// The alpha value to multiply. - /// The hue value to multiply. - /// The saturation value to multiply. - /// The value value to multiply. - /// The new color after the modification. - public Color MultiplyHSV(double a, double hue, double saturation, double value) - => FromHSV((int)Math.Round(A * a), Hue * hue, Saturation * saturation, Value * value); - - /// - /// Multiplies the given alpha value to this color. - /// - /// The alpha value to multiply. - /// The new color after the modification. - public Color MultiplyA(double a) => new Color((int)Math.Round(A * a), R, G, B); - - /// - /// Multiplies the given alpha-percent value to this color. - /// - /// The alpha value to multiply. - /// The new color after the modification. - public Color MultiplyAPercent(double aPercent) => new Color(APercent * aPercent, RPercent, GPercent, BPercent); - - /// - /// Multiplies the given red value to this color. - /// - /// The red value to multiply. - /// The new color after the modification. - public Color MultiplyR(double r) => new Color(A, (int)Math.Round(R * r), G, B); - - /// - /// Multiplies the given red-percent value to this color. - /// - /// The red value to multiply. - /// The new color after the modification. - public Color MultiplyRPercent(double rPercent) => new Color(APercent, RPercent * rPercent, GPercent, BPercent); - - /// - /// Multiplies the given green value to this color. - /// - /// The green value to multiply. - /// The new color after the modification. - public Color MultiplyG(double g) => new Color(A, R, (int)Math.Round(G * g), B); - - /// - /// Multiplies the given green-percent value to this color. - /// - /// The green value to multiply. - /// The new color after the modification. - public Color MultiplyGPercent(double gPercent) => new Color(APercent, RPercent, GPercent * gPercent, BPercent); - - /// - /// Multiplies the given blue value to this color. - /// - /// The blue value to multiply. - /// The new color after the modification. - public Color MultiplyB(double b) => new Color(A, R, G, (int)Math.Round(B * b)); - - /// - /// Multiplies the given blue-percent value to this color. - /// - /// The blue value to multiply. - /// The new color after the modification. - public Color MultiplyBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent * bPercent); - - /// - /// Multiplies the given hue value to this color. - /// - /// The hue value to multiply. - /// The new color after the modification. - public Color MultiplyHue(double hue) => FromHSV(A, Hue * hue, Saturation, Value); - - /// - /// Multiplies the given saturation value to this color. - /// - /// The saturation value to multiply. - /// The new color after the modification. - public Color MultiplySaturation(double saturation) => FromHSV(A, Hue, Saturation * saturation, Value); - - /// - /// Multiplies the given value value to this color. - /// - /// The value value to multiply. - /// The new color after the modification. - public Color MultiplyValue(double value) => FromHSV(A, Hue, Saturation, Value * value); - - #endregion - - #region Divide - - /// - /// Divides the given RGB values to this color. - /// - /// The red value to divide. - /// The green value to divide. - /// The blue value to divide. - /// The new color after the modification. - public Color DivideRGB(double r, double g, double b) => DivideRGB(1, r, g, b); - - /// - /// Divides the given RGB values to this color. - /// - /// The alpha value to divide. - /// The red value to divide. - /// The green value to divide. - /// The blue value to divide. - /// The new color after the modification. - public Color DivideRGB(double a, double r, double g, double b) - => new Color((int)Math.Round(A / a), (int)Math.Round(R / r), (int)Math.Round(G / g), (int)Math.Round(B / b)); - - /// - /// Divides the given RGB-percent values to this color. - /// - /// The red value to divide. - /// The green value to divide. - /// The blue value to divide. - /// The new color after the modification. - public Color DividePercent(double rPercent, double gPercent, double bPercent) => DividePercent(1, rPercent, gPercent, bPercent); - - /// - /// Divides the given RGB-percent values to this color. - /// - /// The alpha value to divide. - /// The red value to divide. - /// The green value to divide. - /// The blue value to divide. - /// The new color after the modification. - public Color DividePercent(double aPercent, double rPercent, double gPercent, double bPercent) - => new Color(APercent / aPercent, RPercent / rPercent, GPercent / gPercent, BPercent / bPercent); - - /// - /// Divides the given HSV values to this color. - /// - /// The hue value to divide. - /// The saturation value to divide. - /// The value value to divide. - /// The new color after the modification. - public Color DivideHSV(double hue, double saturation, double value) => DivideHSV(1, hue, saturation, value); - - /// - /// Divides the given HSV values to this color. - /// - /// The alpha value to divide. - /// The hue value to divide. - /// The saturation value to divide. - /// The value value to divide. - /// The new color after the modification. - public Color DivideHSV(double a, double hue, double saturation, double value) - => FromHSV((int)Math.Round(A / a), Hue / hue, Saturation / saturation, Value / value); - - /// - /// Divides the given alpha value to this color. - /// - /// The alpha value to divide. - /// The new color after the modification. - public Color DivideA(double a) => new Color((int)Math.Round(A / a), R, G, B); - - /// - /// Divides the given alpha-percent value to this color. - /// - /// The alpha value to divide. - /// The new color after the modification. - public Color DivideAPercent(double aPercent) => new Color(APercent / aPercent, RPercent, GPercent, BPercent); - - /// - /// Divides the given red value to this color. - /// - /// The red value to divide. - /// The new color after the modification. - public Color DivideRValue(double r) => new Color(A, (int)Math.Round(R / r), G, B); - - /// - /// Divides the given red-percent value to this color. - /// - /// The red value to divide. - /// The new color after the modification. - public Color DivideRPercent(double rPercent) => new Color(APercent, RPercent / rPercent, GPercent, BPercent); - - /// - /// Divides the given green value to this color. - /// - /// The green value to divide. - /// The new color after the modification. - public Color DivideGValue(double g) => new Color(A, R, (int)Math.Round(G / g), B); - - /// - /// Divides the given green-percent value to this color. - /// - /// The green value to divide. - /// The new color after the modification. - public Color DivideGPercent(double gPercent) => new Color(APercent, RPercent, GPercent / gPercent, BPercent); - - /// - /// Divides the given blue value to this color. - /// - /// The blue value to divide. - /// The new color after the modification. - public Color DivideBValue(double b) => new Color(A, R, G, (int)Math.Round(B / b)); - - /// - /// Divides the given blue-percent value to this color. - /// - /// The blue value to divide. - /// The new color after the modification. - public Color DivideBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent / bPercent); - - /// - /// Divides the given hue value to this color. - /// - /// The hue value to divide. - /// The new color after the modification. - public Color DivideHue(double hue) => FromHSV(A, Hue / hue, Saturation, Value); - - /// - /// Divides the given saturation value to this color. - /// - /// The saturation value to divide. - /// The new color after the modification. - public Color DivideSaturation(double saturation) => FromHSV(A, Hue, Saturation / saturation, Value); - - /// - /// Divides the given value value to this color. - /// - /// The value value to divide. - /// The new color after the modification. - public Color DivideValue(double value) => FromHSV(A, Hue, Saturation, Value / value); - - #endregion - - #region Set - - /// - /// Sets the given alpha value of this color. - /// - /// The alpha value to set. - /// The new color after the modification. - public Color SetA(int a) => new Color(a, R, G, B); - - /// - /// Sets the given alpha-percent value of this color. - /// - /// The alpha value to set. - /// The new color after the modification. - public Color SetAPercent(double aPercent) => new Color(aPercent, RPercent, GPercent, BPercent); - - /// - /// Sets the given red value of this color. - /// - /// The red value to set. - /// The new color after the modification. - public Color SetR(int r) => new Color(A, r, G, B); - - /// - /// Sets the given red-percent value of this color. - /// - /// The red value to set. - /// The new color after the modification. - public Color SetRPercent(double rPercent) => new Color(APercent, rPercent, GPercent, BPercent); - - /// - /// Sets the given green value of this color. - /// - /// The green value to set. - /// The new color after the modification. - public Color SetG(int g) => new Color(A, R, g, B); - - /// - /// Sets the given green-percent value of this color. - /// - /// The green value to set. - /// The new color after the modification. - public Color SetGPercent(double gPercent) => new Color(APercent, RPercent, gPercent, BPercent); - - /// - /// Sets the given blue value of this color. - /// - /// The blue value to set. - /// The new color after the modification. - public Color SetB(int b) => new Color(A, R, G, b); - - /// - /// Sets the given blue-percent value of this color. - /// - /// The blue value to set. - /// The new color after the modification. - public Color SetBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, bPercent); - - /// - /// Sets the given hue value of this color. - /// - /// The hue value to set. - /// The new color after the modification. - public Color SetHue(double hue) => FromHSV(A, hue, Saturation, Value); - - /// - /// Sets the given saturation value of this color. - /// - /// The saturation value to set. - /// The new color after the modification. - public Color SetSaturation(double saturation) => FromHSV(A, Hue, saturation, Value); - - /// - /// Sets the given value value of this color. - /// - /// The value value to set. - /// The new color after the modification. - public Color SetValue(double value) => FromHSV(A, Hue, Saturation, value); - - #endregion - - #endregion - - #endregion - - #region Operators - - /// - /// Blends the provided colors as if would've been called on . - /// - /// The base color. - /// The color to blend. - /// The blended color. - public static Color operator +(Color color1, Color color2) => color1.Blend(color2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Color color1, Color color2) => color1.Equals(color2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Color color1, Color color2) => !(color1 == color2); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b); - - /// - /// Converts a of HSV-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((double hue, double saturation, double value) components) => new Color(components.hue, components.saturation, components.value); - - #endregion - } -} diff --git a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings index d88c562..739bd7f 100644 --- a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings +++ b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings @@ -1,5 +1,6 @@  True + True True True True diff --git a/RGB.NET.Decorators/Brush/FlashDecorator.cs b/RGB.NET.Decorators/Brush/FlashDecorator.cs index dd84f2c..618b243 100644 --- a/RGB.NET.Decorators/Brush/FlashDecorator.cs +++ b/RGB.NET.Decorators/Brush/FlashDecorator.cs @@ -77,7 +77,7 @@ namespace RGB.NET.Decorators.Brush #region Methods /// - public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetAPercent(_currentValue); + public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetA(_currentValue); /// protected override void Update(double deltaTime) diff --git a/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs index 65460e2..a3570c9 100644 --- a/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs +++ b/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs @@ -40,14 +40,16 @@ namespace RGB.NET.Devices.Novation /// The novation-representation of the . protected virtual int ConvertColor(Color color) { - if ((color.Hue >= 330) || (color.Hue < 30)) - return (int)Math.Ceiling(color.Value * 3); // red with brightness 1, 2 or 3 + (double hue, double saturation, double value) = color.GetHSV(); - if ((color.Hue >= 30) && (color.Hue < 90)) // yellow with brightness 17, 34 or 51 - return (int)Math.Ceiling(color.Value * 3) * 17; + if ((hue >= 330) || (hue < 30)) + return (int)Math.Ceiling(value * 3); // red with brightness 1, 2 or 3 - if ((color.Hue >= 90) && (color.Hue < 150)) // green with brightness 16, 32 or 48 - return (int)Math.Ceiling(color.Value * 3) * 16; + if ((hue >= 30) && (hue < 90)) // yellow with brightness 17, 34 or 51 + return (int)Math.Ceiling(value * 3) * 17; + + if ((hue >= 90) && (hue < 150)) // green with brightness 16, 32 or 48 + return (int)Math.Ceiling(value * 3) * 16; return 0; } diff --git a/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs b/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs index 0ba9697..c3bec0f 100644 --- a/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs +++ b/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs @@ -66,7 +66,7 @@ namespace RGB.NET.Devices.SoIP.Client List<(LedId, Color)> leds = message.MessageString.Split(';').Select(x => { string[] led = x.Split('|'); - return ((LedId)Enum.Parse(typeof(LedId), led[0]), Color.FromHexString(led[1])); + return ((LedId)Enum.Parse(typeof(LedId), led[0]), RGBColor.FromHexString(led[1])); }).ToList(); lock (_syncbackCache) foreach ((LedId ledId, Color color) in leds) diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs index 79c20a1..5a5285e 100644 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs +++ b/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs @@ -61,7 +61,7 @@ namespace RGB.NET.Devices.SoIP.Server tcpClient.GetStream().WriteAsync(messageData, 0, messageData.Length); } - private string GetLedString(IEnumerable leds) => string.Join(";", leds.Select(x => x.Id.ToString() + "|" + x.Color.AsARGBHexString())); + private string GetLedString(IEnumerable leds) => string.Join(";", leds.Select(x => x.Id.ToString() + "|" + x.Color.AsARGBHexString(false))); /// public override void Dispose() diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs index 999ef9c..1d100ce 100644 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs +++ b/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs @@ -46,7 +46,7 @@ namespace RGB.NET.Devices.SoIP.Server } } - private string GetLedString(Dictionary dataSet) => string.Join(";", dataSet.Select(x => x.Key.ToString() + "|" + x.Value.AsARGBHexString())); + private string GetLedString(Dictionary dataSet) => string.Join(";", dataSet.Select(x => x.Key.ToString() + "|" + x.Value.AsARGBHexString(false))); #endregion } diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs index 4ea1152..5b70008 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs @@ -39,7 +39,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard protected override IEnumerable GetCommands(Dictionary dataSet) { foreach (KeyValuePair data in dataSet) - yield return $"pix {(int)data.Key} {data.Value.AsRGBHexString()}"; + yield return $"pix {(int)data.Key} {data.Value.AsRGBHexString(false)}"; } #endregion diff --git a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs index 6d5c9ba..823a203 100644 --- a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs @@ -6,85 +6,61 @@ namespace RGB.NET.Core.Tests.Color public class HSVColorTest { #region Manipulation - - #region Blend - - [TestMethod] - public void BlendOpaqueTest() - { - Assert.Inconclusive(); - //Core.Color baseColor = new Core.Color(255, 0, 0); - //Core.Color blendColor = new Core.Color(0, 255, 0); - - //Assert.AreEqual(blendColor, baseColor.Blend(blendColor)); - } - - [TestMethod] - public void BlendTransparentTest() - { - Assert.Inconclusive(); - //Core.Color baseColor = new Core.Color(255, 0, 0); - //Core.Color blendColor = new Core.Color(0, 0, 255, 0); - - //Assert.AreEqual(baseColor, baseColor.Blend(blendColor)); - } - - #endregion - + #region Add [TestMethod] public void AddHueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.AddHue(30); - - Assert.AreEqual(Core.Color.FromHSV(210, 0.5, 0.5), result); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.AddHSV(hue: 30); + + Assert.AreEqual(HSVColor.Create(210, 0.5, 0.5), result); } [TestMethod] public void AddHueWrapTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.AddHue(220); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.AddHSV(hue: 220); - Assert.AreEqual(Core.Color.FromHSV(40, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(40, 0.5, 0.5), result); } [TestMethod] public void AddSaturationTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.AddSaturation(0.3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.AddHSV(saturation: 0.3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.8, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 0.8, 0.5), result); } [TestMethod] public void AddSaturationClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.AddSaturation(0.8); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.AddHSV(saturation: 0.8); - Assert.AreEqual(Core.Color.FromHSV(180, 1.0, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result); } [TestMethod] public void AddValueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.AddValue(0.3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.AddHSV(value: 0.3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.8), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 0.8), result); } [TestMethod] public void AddValueClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.AddValue(0.8); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.AddHSV(value: 0.8); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 1.0), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result); } #endregion @@ -94,55 +70,55 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractHueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHue(30); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHSV(hue: 30); - Assert.AreEqual(Core.Color.FromHSV(150, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(150, 0.5, 0.5), result); } [TestMethod] public void SubtractHueWrapTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHue(220); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHSV(hue: 220); - Assert.AreEqual(Core.Color.FromHSV(320, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(320, 0.5, 0.5), result); } [TestMethod] public void SubtractSaturationTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractSaturation(0.3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHSV(saturation: 0.3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.2, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 0.2, 0.5), result); } [TestMethod] public void SubtractSaturationClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractSaturation(0.8); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHSV(saturation: 0.8); - Assert.AreEqual(Core.Color.FromHSV(180, 0, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 0, 0.5), result); } [TestMethod] public void SubtractValueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractValue(0.3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHSV(value: 0.3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.2), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 0.2), result); } [TestMethod] public void SubtractValueClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractValue(0.8); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SubtractHSV(value: .8); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 0), result); } #endregion @@ -152,55 +128,55 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void MultiplyHueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyHue(1.5); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyHSV(hue: 1.5); - Assert.AreEqual(Core.Color.FromHSV(270, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(270, 0.5, 0.5), result); } [TestMethod] public void MultiplyHueWrapTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyHue(3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyHSV(hue: 3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 0.5), result); } [TestMethod] public void MultiplySaturationTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.2, 0.2); - Core.Color result = baseColor.MultiplySaturation(3); + Core.Color baseColor = HSVColor.Create(180, 0.2, 0.2); + Core.Color result = baseColor.MultiplyHSV(saturation: 3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.6, 0.2), result); + Assert.AreEqual(HSVColor.Create(180, 0.6, 0.2), result); } [TestMethod] public void MultiplySaturationClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplySaturation(3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyHSV(saturation: 3); - Assert.AreEqual(Core.Color.FromHSV(180, 1.0, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result); } [TestMethod] public void MultiplyValueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.2, 0.2); - Core.Color result = baseColor.MultiplyValue(3); + Core.Color baseColor = HSVColor.Create(180, 0.2, 0.2); + Core.Color result = baseColor.MultiplyHSV(value: 3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.2, 0.6), result); + Assert.AreEqual(HSVColor.Create(180, 0.2, 0.6), result); } [TestMethod] public void MultiplyValueClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyValue(3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.MultiplyHSV(value: 3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 1.0), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result); } #endregion @@ -210,28 +186,28 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void DivideHueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.DivideHue(30); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.DivideHSV(hue: 30); - Assert.AreEqual(Core.Color.FromHSV(6, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(6, 0.5, 0.5), result); } [TestMethod] public void DivideSaturationTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.6, 0.6); - Core.Color result = baseColor.DivideSaturation(2); + Core.Color baseColor = HSVColor.Create(180, 0.6, 0.6); + Core.Color result = baseColor.DivideHSV(saturation: 2); - Assert.AreEqual(Core.Color.FromHSV(180, 0.3, 0.6), result); + Assert.AreEqual(HSVColor.Create(180, 0.3, 0.6), result); } [TestMethod] public void DivideValueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.6, 0.6); - Core.Color result = baseColor.DivideValue(2); + Core.Color baseColor = HSVColor.Create(180, 0.6, 0.6); + Core.Color result = baseColor.DivideHSV(value: 2); - Assert.AreEqual(Core.Color.FromHSV(180, 0.6, 0.3), result); + Assert.AreEqual(HSVColor.Create(180, 0.6, 0.3), result); } #endregion @@ -241,64 +217,64 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetHueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetHue(30); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(hue: 30); - Assert.AreEqual(Core.Color.FromHSV(30, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(30, 0.5, 0.5), result); } [TestMethod] public void SetHueWrapTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetHue(440); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(hue: 440); - Assert.AreEqual(Core.Color.FromHSV(80, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(80, 0.5, 0.5), result); } [TestMethod] public void SetHueWrapNegativeTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetHue(-30); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(hue: -30); - Assert.AreEqual(Core.Color.FromHSV(330, 0.5, 0.5), result); + Assert.AreEqual(HSVColor.Create(330, 0.5, 0.5), result); } [TestMethod] public void SetSaturationTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetSaturation(0.3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(saturation: 0.3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.3, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 0.3, 0.5), result); } [TestMethod] public void SetSaturationClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetSaturation(2); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(saturation: 2); - Assert.AreEqual(Core.Color.FromHSV(180, 1.0, 0.5), result); + Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result); } [TestMethod] public void SetValueTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetValue(0.3); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(value: 0.3); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 0.3), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 0.3), result); } [TestMethod] public void SetValueClampTest() { - Core.Color baseColor = Core.Color.FromHSV(180, 0.5, 0.5); - Core.Color result = baseColor.SetValue(2); + Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); + Core.Color result = baseColor.SetHSV(value: 2); - Assert.AreEqual(Core.Color.FromHSV(180, 0.5, 1.0), result); + Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result); } #endregion diff --git a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs index f2753e7..2624444 100644 --- a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs @@ -40,7 +40,7 @@ namespace RGB.NET.Core.Tests.Color public void BlendDownTest() { Core.Color baseColor = new Core.Color(1.0, 1.0, 1.0); - Core.Color blendColor = new Core.Color(1.0, 0.0, 0.0, 0.0); + Core.Color blendColor = new Core.Color(0.5, 0.0, 0.0, 0.0); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); } @@ -58,33 +58,15 @@ namespace RGB.NET.Core.Tests.Color Assert.AreEqual(new Core.Color(128, 139, 140, 141), result); } - [TestMethod] - public void AddARGBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddRGB(10, 11, 12, 13); - - Assert.AreEqual(new Core.Color(138, 139, 140, 141), result); - } - [TestMethod] public void AddRGBPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddPercent(0.2, 0.3, 0.4); + Core.Color result = baseColor.AddRGB(0.2, 0.3, 0.4); Assert.AreEqual(new Core.Color(0.5, 0.7, 0.8, 0.9), result); } - [TestMethod] - public void AddARGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddPercent(0.1, 0.2, 0.3, 0.4); - - Assert.AreEqual(new Core.Color(0.6, 0.7, 0.8, 0.9), result); - } - [TestMethod] public void AddATest() { @@ -98,7 +80,7 @@ namespace RGB.NET.Core.Tests.Color public void AddAPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddAPercent(0.1); + Core.Color result = baseColor.AddA(0.1); Assert.AreEqual(new Core.Color(0.6, 0.5, 0.5, 0.5), result); } @@ -107,7 +89,7 @@ namespace RGB.NET.Core.Tests.Color public void AddRTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddR(10); + Core.Color result = baseColor.AddRGB(r: 10); Assert.AreEqual(new Core.Color(128, 138, 128, 128), result); } @@ -116,7 +98,7 @@ namespace RGB.NET.Core.Tests.Color public void AddRPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddRPercent(0.1); + Core.Color result = baseColor.AddRGB(r: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.6, 0.5, 0.5), result); } @@ -125,7 +107,7 @@ namespace RGB.NET.Core.Tests.Color public void AddGTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddG(10); + Core.Color result = baseColor.AddRGB(g: 10); Assert.AreEqual(new Core.Color(128, 128, 138, 128), result); } @@ -134,7 +116,7 @@ namespace RGB.NET.Core.Tests.Color public void AddGPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddGPercent(0.1); + Core.Color result = baseColor.AddRGB(g: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.6, 0.5), result); } @@ -143,7 +125,7 @@ namespace RGB.NET.Core.Tests.Color public void AddBTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddB(10); + Core.Color result = baseColor.AddRGB(b: 10); Assert.AreEqual(new Core.Color(128, 128, 128, 138), result); } @@ -152,7 +134,7 @@ namespace RGB.NET.Core.Tests.Color public void AddBPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddBPercent(0.1); + Core.Color result = baseColor.AddRGB(b: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.6), result); } @@ -170,33 +152,15 @@ namespace RGB.NET.Core.Tests.Color Assert.AreEqual(new Core.Color(128, 117, 116, 115), result); } - [TestMethod] - public void SubtractARGBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractRGB(10, 11, 12, 13); - - Assert.AreEqual(new Core.Color(118, 117, 116, 115), result); - } - [TestMethod] public void SubtractRGBPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractPercent(0.2, 0.3, 0.4); + Core.Color result = baseColor.SubtractRGB(0.2, 0.3, 0.4); Assert.AreEqual(new Core.Color(0.5, 0.3, 0.2, 0.1), result); } - [TestMethod] - public void SubtractARGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractPercent(0.1, 0.2, 0.3, 0.4); - - Assert.AreEqual(new Core.Color(0.4, 0.3, 0.2, 0.1), result); - } - [TestMethod] public void SubtractATest() { @@ -210,7 +174,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractAPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractAPercent(0.1); + Core.Color result = baseColor.SubtractA(0.1); Assert.AreEqual(new Core.Color(0.4, 0.5, 0.5, 0.5), result); } @@ -219,7 +183,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractRTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractR(10); + Core.Color result = baseColor.SubtractRGB(r: 10); Assert.AreEqual(new Core.Color(128, 118, 128, 128), result); } @@ -228,7 +192,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractRPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractRPercent(0.1); + Core.Color result = baseColor.SubtractRGB(r: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.4, 0.5, 0.5), result); } @@ -237,7 +201,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractGTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractG(10); + Core.Color result = baseColor.SubtractRGB(g: 10); Assert.AreEqual(new Core.Color(128, 128, 118, 128), result); } @@ -246,7 +210,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractGPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractGPercent(0.1); + Core.Color result = baseColor.SubtractRGB(g: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.4, 0.5), result); } @@ -255,7 +219,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractBTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractB(10); + Core.Color result = baseColor.SubtractRGB(b: 10); Assert.AreEqual(new Core.Color(128, 128, 128, 118), result); } @@ -264,7 +228,7 @@ namespace RGB.NET.Core.Tests.Color public void SubtractBPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractBPercent(0.1); + Core.Color result = baseColor.SubtractRGB(b: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.4), result); } @@ -277,25 +241,16 @@ namespace RGB.NET.Core.Tests.Color public void MultiplyRGBPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyPercent(3, 4, 5); + Core.Color result = baseColor.MultiplyRGB(3, 4, 5); Assert.AreEqual(new Core.Color(0.2, 0.6, 0.8, 1.0), result); } - [TestMethod] - public void MultiplyARGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyPercent(2, 3, 4, 5); - - Assert.AreEqual(new Core.Color(0.4, 0.6, 0.8, 1.0), result); - } - [TestMethod] public void MultiplyAPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyAPercent(3); + Core.Color result = baseColor.MultiplyA(3); Assert.AreEqual(new Core.Color(0.6, 0.2, 0.2, 0.2), result); } @@ -304,7 +259,7 @@ namespace RGB.NET.Core.Tests.Color public void MultiplyRPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyRPercent(3); + Core.Color result = baseColor.MultiplyRGB(r: 3); Assert.AreEqual(new Core.Color(0.2, 0.6, 0.2, 0.2), result); } @@ -313,7 +268,7 @@ namespace RGB.NET.Core.Tests.Color public void MultiplyGPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyGPercent(3); + Core.Color result = baseColor.MultiplyRGB(g: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.6, 0.2), result); } @@ -322,7 +277,7 @@ namespace RGB.NET.Core.Tests.Color public void MultiplyBPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyBPercent(3); + Core.Color result = baseColor.MultiplyRGB(b: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.6), result); } @@ -335,16 +290,7 @@ namespace RGB.NET.Core.Tests.Color public void DivideRGBPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.6, 0.8, 1.0); - Core.Color result = baseColor.DividePercent(3, 4, 5); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); - } - - [TestMethod] - public void DivideARGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.4, 0.6, 0.8, 1.0); - Core.Color result = baseColor.DividePercent(2, 3, 4, 5); + Core.Color result = baseColor.DivideRGB(3, 4, 5); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); } @@ -353,7 +299,7 @@ namespace RGB.NET.Core.Tests.Color public void DivideAPercentTest() { Core.Color baseColor = new Core.Color(0.6, 0.2, 0.2, 0.2); - Core.Color result = baseColor.DivideAPercent(3); + Core.Color result = baseColor.DivideA(3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); } @@ -362,7 +308,7 @@ namespace RGB.NET.Core.Tests.Color public void DivideRPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.6, 0.2, 0.2); - Core.Color result = baseColor.DivideRPercent(3); + Core.Color result = baseColor.DivideRGB(r: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); } @@ -371,7 +317,7 @@ namespace RGB.NET.Core.Tests.Color public void DivideGPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.6, 0.2); - Core.Color result = baseColor.DivideGPercent(3); + Core.Color result = baseColor.DivideRGB(g: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); } @@ -380,7 +326,7 @@ namespace RGB.NET.Core.Tests.Color public void DivideBPercentTest() { Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.6); - Core.Color result = baseColor.DivideBPercent(3); + Core.Color result = baseColor.DivideRGB(b: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); } @@ -393,38 +339,20 @@ namespace RGB.NET.Core.Tests.Color public void SetRGBTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetR(11).SetG(12).SetB(13); + Core.Color result = baseColor.SetRGB(11, 12, 13); Assert.AreEqual(new Core.Color(128, 11, 12, 13), result); } - [TestMethod] - public void SetARGBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetA(10).SetR(11).SetG(12).SetB(13); - - Assert.AreEqual(new Core.Color(10, 11, 12, 13), result); - } - [TestMethod] public void SetRGBPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetRPercent(0.2).SetGPercent(0.3).SetBPercent(0.4); + Core.Color result = baseColor.SetRGB(0.2, 0.3, 0.4); Assert.AreEqual(new Core.Color(0.5, 0.2, 0.3, 0.4), result); } - [TestMethod] - public void SetARGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetAPercent(0.1).SetRPercent(0.2).SetGPercent(0.3).SetBPercent(0.4); - - Assert.AreEqual(new Core.Color(0.1, 0.2, 0.3, 0.4), result); - } - [TestMethod] public void SetATest() { @@ -438,7 +366,7 @@ namespace RGB.NET.Core.Tests.Color public void SetAPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetAPercent(0.1); + Core.Color result = baseColor.SetA(0.1); Assert.AreEqual(new Core.Color(0.1, 0.5, 0.5, 0.5), result); } @@ -447,7 +375,7 @@ namespace RGB.NET.Core.Tests.Color public void SetRTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetR(10); + Core.Color result = baseColor.SetRGB(r: 10); Assert.AreEqual(new Core.Color(128, 10, 128, 128), result); } @@ -456,7 +384,7 @@ namespace RGB.NET.Core.Tests.Color public void SetRPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetRPercent(0.1); + Core.Color result = baseColor.SetRGB(r: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.1, 0.5, 0.5), result); } @@ -465,7 +393,7 @@ namespace RGB.NET.Core.Tests.Color public void SetGTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetG(10); + Core.Color result = baseColor.SetRGB(g: 10); Assert.AreEqual(new Core.Color(128, 128, 10, 128), result); } @@ -474,7 +402,7 @@ namespace RGB.NET.Core.Tests.Color public void SetGPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetGPercent(0.1); + Core.Color result = baseColor.SetRGB(g: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.1, 0.5), result); } @@ -483,7 +411,7 @@ namespace RGB.NET.Core.Tests.Color public void SetBTest() { Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetB(10); + Core.Color result = baseColor.SetRGB(b: 10); Assert.AreEqual(new Core.Color(128, 128, 128, 10), result); } @@ -492,7 +420,7 @@ namespace RGB.NET.Core.Tests.Color public void SetBPercentTest() { Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetBPercent(0.1); + Core.Color result = baseColor.SetRGB(b: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.1), result); } From 0895627ccf0911ee861b708a97560a75ea4bfc31 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 24 Feb 2019 17:56:49 +0100 Subject: [PATCH 4/8] Fixed color-operators --- RGB.NET.Core/Color/Color.cs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs index 3c0667e..20d7f9c 100644 --- a/RGB.NET.Core/Color/Color.cs +++ b/RGB.NET.Core/Color/Color.cs @@ -320,14 +320,42 @@ namespace RGB.NET.Core /// /// The containing the components. /// The color. - public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b); + public static implicit operator Color((byte r, byte g, byte b) components) => new Color(components.r, components.g, components.b); /// - /// Converts a of HSV-components to a . + /// Converts a of ARGB-components to a . /// /// The containing the components. /// The color. - public static implicit operator Color((double hue, double saturation, double value) components) => new Color(components.hue, components.saturation, components.value); + public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((int r, int g, int b) components) => new Color(components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((int a, int r, int g, int b) components) => new Color(components.a, components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((double r, double g, double b) components) => new Color(components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((double a, double r, double g, double b) components) => new Color(components.a, components.r, components.g, components.b); #endregion } From 558eb3eb5a870b9de59bb37fed5ed69c4586d84f Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 24 Feb 2019 18:00:12 +0100 Subject: [PATCH 5/8] Added missing doc-comments --- RGB.NET.Core/Color/HSVColor.cs | 23 +++++++++++++++++++++++ RGB.NET.Core/Color/RGBColor.cs | 9 +++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs index e632e6c..e1562b1 100644 --- a/RGB.NET.Core/Color/HSVColor.cs +++ b/RGB.NET.Core/Color/HSVColor.cs @@ -6,12 +6,35 @@ namespace RGB.NET.Core { #region Getter + /// + /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360]. + /// + /// + /// public static double GetHue(this Color color) => color.GetHSV().hue; + /// + /// Gets the saturation component value (HSV-color space) of this in the range [0..1]. + /// + /// + /// public static double GetSaturation(this Color color) => color.GetHSV().saturation; + /// + /// Gets the value component value (HSV-color space) of this in the range [0..1]. + /// + /// + /// public static double GetValue(this Color color) => color.GetHSV().value; + /// + /// Gets the hue, saturation and value component values (HSV-color space) of this . + /// Hue as degree in the range [0..1]. + /// Saturation in the range [0..1]. + /// Value in the range [0..1]. + /// + /// + /// public static (double hue, double saturation, double value) GetHSV(this Color color) => CaclulateHSVFromRGB(color.RPercent, color.GPercent, color.BPercent); diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs index fa26417..2aa3b74 100644 --- a/RGB.NET.Core/Color/RGBColor.cs +++ b/RGB.NET.Core/Color/RGBColor.cs @@ -6,8 +6,13 @@ namespace RGB.NET.Core { #region Getter - public static (double r, double g, double b) GetRGBPercent(this Color color) - => (color.RPercent, color.GPercent, color.BPercent); + /// + /// Gets the A, R, G and B component value of this as percentage in the range [0..1]. + /// + /// + /// + public static (double a, double r, double g, double b) GetRGBPercent(this Color color) + => (color.APercent, color.RPercent, color.GPercent, color.BPercent); #endregion From fa396127ea54978db292da5a6df947675b0a875b Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Mon, 25 Feb 2019 20:57:01 +0100 Subject: [PATCH 6/8] Removed byte-component from color --- RGB.NET.Brushes/Gradients/LinearGradient.cs | 8 +- RGB.NET.Core/Color/Color.cs | 105 ++------ RGB.NET.Core/Color/HSVColor.cs | 22 +- RGB.NET.Core/Color/RGBColor.cs | 78 ++++-- .../Generic/AsusUpdateQueue.cs | 6 +- .../Generic/CoolerMasterUpdateQueue.cs | 2 +- .../Generic/CorsairDeviceUpdateQueue.cs | 6 +- .../PerDevice/LogitechPerDeviceUpdateQueue.cs | 6 +- .../PerKey/BitmapMapping.cs | 8 +- .../PerKey/LogitechPerKeyUpdateQueue.cs | 6 +- .../Zone/LogitechZoneUpdateQueue.cs | 6 +- RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs | 2 +- RGB.NET.Devices.Razer/Native/_Color.cs | 2 +- .../Arduino/ArduinoWS2812USBUpdateQueue.cs | 2 +- Tests/RGB.NET.Core.Tests/Color/ColorTest.cs | 238 +++++++++--------- 15 files changed, 241 insertions(+), 256 deletions(-) diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Brushes/Gradients/LinearGradient.cs index c8f9227..535fe5d 100644 --- a/RGB.NET.Brushes/Gradients/LinearGradient.cs +++ b/RGB.NET.Brushes/Gradients/LinearGradient.cs @@ -97,10 +97,10 @@ namespace RGB.NET.Brushes.Gradients if (!gsBefore.Offset.Equals(gsAfter.Offset)) blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset)); - byte colA = (byte)(((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A); - byte colR = (byte)(((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R); - byte colG = (byte)(((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G); - byte colB = (byte)(((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B); + double colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A; + double colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R; + double colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G; + double colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B; return new Color(colA, colR, colG, colB); } diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs index 20d7f9c..0d5a028 100644 --- a/RGB.NET.Core/Color/Color.cs +++ b/RGB.NET.Core/Color/Color.cs @@ -25,45 +25,25 @@ namespace RGB.NET.Core #region Properties & Fields - /// - /// Gets the alpha component value of this as byte in the range [0..255]. - /// - public byte A { get; } - /// /// Gets the alpha component value of this as percentage in the range [0..1]. /// - public double APercent { get; } - - /// - /// Gets the red component value of this as byte in the range [0..255]. - /// - public byte R { get; } + public double A { get; } /// /// Gets the red component value of this as percentage in the range [0..1]. /// - public double RPercent { get; } - - /// - /// Gets the green component value of this as byte in the range [0..255]. - /// - public byte G { get; } + public double R { get; } /// /// Gets the green component value of this as percentage in the range [0..1]. /// - public double GPercent { get; } - - /// - /// Gets the blue component value of this as byte in the range [0..255]. - /// - public byte B { get; } + public double G { get; } /// /// Gets the blue component value of this as percentage in the range [0..1]. /// - public double BPercent { get; } + public double B { get; } #endregion @@ -101,7 +81,7 @@ namespace RGB.NET.Core /// The green component value of this . /// The blue component value of this . public Color(byte a, byte r, byte g, byte b) - : this(a, r, g, b, a.GetPercentageFromByteValue(), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) + : this(a.GetPercentageFromByteValue(), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) { } /// @@ -134,8 +114,7 @@ namespace RGB.NET.Core /// The green component value of this . /// The blue component value of this . public Color(double a, byte r, byte g, byte b) - : this(a.GetByteValueFromPercentage(), r, g, b, - a.Clamp(0, 1), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) + : this(a, r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) { } /// @@ -168,8 +147,7 @@ namespace RGB.NET.Core /// The green component value of this . /// The blue component value of this . public Color(byte a, double r, double g, double b) - : this(a, r.GetByteValueFromPercentage(), g.GetByteValueFromPercentage(), b.GetByteValueFromPercentage(), - a.GetPercentageFromByteValue(), r.Clamp(0, 1), g.Clamp(0, 1), b.Clamp(0, 1)) + : this(a.GetPercentageFromByteValue(), r, g, b) { } /// @@ -180,9 +158,12 @@ namespace RGB.NET.Core /// The green component value of this . /// The blue component value of this . public Color(double a, double r, double g, double b) - : this(a.GetByteValueFromPercentage(), r.GetByteValueFromPercentage(), g.GetByteValueFromPercentage(), b.GetByteValueFromPercentage(), - a.Clamp(0, 1), r.Clamp(0, 1), g.Clamp(0, 1), b.Clamp(0, 1)) - { } + { + A = a.Clamp(0, 1); + R = r.Clamp(0, 1); + G = g.Clamp(0, 1); + B = b.Clamp(0, 1); + } /// /// @@ -190,22 +171,9 @@ namespace RGB.NET.Core /// /// The the values are copied from. public Color(Color color) - : this(color.APercent, color.RPercent, color.GPercent, color.BPercent) + : this(color.A, color.R, color.G, color.B) { } - private Color(byte a, byte r, byte g, byte b, double aP, double rP, double gP, double bP) - { - this.A = a; - this.R = r; - this.G = g; - this.B = b; - - this.APercent = aP; - this.RPercent = rP; - this.GPercent = gP; - this.BPercent = bP; - } - #endregion #region Methods @@ -214,7 +182,7 @@ namespace RGB.NET.Core /// Converts the individual byte values of this to a human-readable string. /// /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". - public override string ToString() => $"[A: {A}, R: {R}, G: {G}, B: {B}]"; + public override string ToString() => $"[A: {this.GetA()}, R: {this.GetR()}, G: {this.GetG()}, B: {this.GetB()}]"; /// /// Tests whether the specified object is a and is equivalent to this . @@ -225,8 +193,8 @@ namespace RGB.NET.Core { if (!(obj is Color)) return false; - (byte a, byte r, byte g, byte b) = (Color)obj; - return (a == A) && (r == R) && (g == G) && (b == B); + (double a, double r, double g, double b) = ((Color)obj).GetRGB(); + return A.EqualsInTolerance(a) && R.EqualsInTolerance(r) && G.EqualsInTolerance(g) && B.EqualsInTolerance(b); } /// @@ -237,33 +205,14 @@ namespace RGB.NET.Core { unchecked { - int hashCode = APercent.GetHashCode(); - hashCode = (hashCode * 397) ^ RPercent.GetHashCode(); - hashCode = (hashCode * 397) ^ GPercent.GetHashCode(); - hashCode = (hashCode * 397) ^ BPercent.GetHashCode(); + int hashCode = A.GetHashCode(); + hashCode = (hashCode * 397) ^ R.GetHashCode(); + hashCode = (hashCode * 397) ^ G.GetHashCode(); + hashCode = (hashCode * 397) ^ B.GetHashCode(); return hashCode; } } - #region Deconstruction - - /// - /// Deconstructs the Color into it's ARGB-components. - /// - /// The alpha component of this color. - /// The red component of this color. - /// The green component of this color. - /// The blue component of this color. - public void Deconstruct(out byte a, out byte r, out byte g, out byte b) - { - a = A; - r = R; - g = G; - b = B; - } - - #endregion - #region Manipulation /// @@ -272,15 +221,15 @@ namespace RGB.NET.Core /// The to blend. public Color Blend(Color color) { - if (color.A == 0) return this; + if (color.A.EqualsInTolerance(0)) return this; - if (color.A == 255) + if (color.A.EqualsInTolerance(1)) return color; - double resultA = (1.0 - ((1.0 - color.APercent) * (1.0 - APercent))); - double resultR = (((color.RPercent * color.APercent) / resultA) + ((RPercent * APercent * (1.0 - color.APercent)) / resultA)); - double resultG = (((color.GPercent * color.APercent) / resultA) + ((GPercent * APercent * (1.0 - color.APercent)) / resultA)); - double resultB = (((color.BPercent * color.APercent) / resultA) + ((BPercent * APercent * (1.0 - color.APercent)) / resultA)); + double resultA = (1.0 - ((1.0 - color.A) * (1.0 - A))); + double resultR = (((color.R * color.A) / resultA) + ((R * A * (1.0 - color.A)) / resultA)); + double resultG = (((color.G * color.A) / resultA) + ((G * A * (1.0 - color.A)) / resultA)); + double resultB = (((color.B * color.A) / resultA) + ((B * A * (1.0 - color.A)) / resultA)); return new Color(resultA, resultR, resultG, resultB); } diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs index e1562b1..21bb5b1 100644 --- a/RGB.NET.Core/Color/HSVColor.cs +++ b/RGB.NET.Core/Color/HSVColor.cs @@ -36,7 +36,7 @@ namespace RGB.NET.Core /// /// public static (double hue, double saturation, double value) GetHSV(this Color color) - => CaclulateHSVFromRGB(color.RPercent, color.GPercent, color.BPercent); + => CaclulateHSVFromRGB(color.R, color.G, color.B); #endregion @@ -52,7 +52,7 @@ namespace RGB.NET.Core public static Color AddHSV(this Color color, double hue = 0, double saturation = 0, double value = 0) { (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.APercent, cHue + hue, cSaturation + saturation, cValue + value); + return Create(color.A, cHue + hue, cSaturation + saturation, cValue + value); } /// @@ -65,7 +65,7 @@ namespace RGB.NET.Core public static Color SubtractHSV(this Color color, double hue = 0, double saturation = 0, double value = 0) { (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.APercent, cHue - hue, cSaturation - saturation, cValue - value); + return Create(color.A, cHue - hue, cSaturation - saturation, cValue - value); } /// @@ -78,7 +78,7 @@ namespace RGB.NET.Core public static Color MultiplyHSV(this Color color, double hue = 1, double saturation = 1, double value = 1) { (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.APercent, cHue * hue, cSaturation * saturation, cValue * value); + return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value); } @@ -92,7 +92,7 @@ namespace RGB.NET.Core public static Color DivideHSV(this Color color, double hue = 1, double saturation = 1, double value = 1) { (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.APercent, cHue / hue, cSaturation / saturation, cValue / value); + return Create(color.A, cHue / hue, cSaturation / saturation, cValue / value); } /// @@ -105,7 +105,7 @@ namespace RGB.NET.Core public static Color SetHSV(this Color color, double? hue = null, double? saturation = null, double? value = null) { (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.APercent, hue ?? cHue, saturation ?? cSaturation, value ?? cValue); + return Create(color.A, hue ?? cHue, saturation ?? cSaturation, value ?? cValue); } #endregion @@ -164,17 +164,17 @@ namespace RGB.NET.Core private static (double h, double s, double v) CaclulateHSVFromRGB(double r, double g, double b) { - if ((r == g) && (g == b)) return (0, 0, r); + if (r.EqualsInTolerance(g) && g.EqualsInTolerance(b)) return (0, 0, r); double min = Math.Min(Math.Min(r, g), b); double max = Math.Max(Math.Max(r, g), b); double hue; - if (max == min) + if (max.EqualsInTolerance(min)) hue = 0; - else if (max == r) // r is max + else if (max.EqualsInTolerance(r)) // r is max hue = (g - b) / (max - min); - else if (max == g) // g is max + else if (max.EqualsInTolerance(g)) // g is max hue = 2.0 + ((b - r) / (max - min)); else // b is max hue = 4.0 + ((r - g) / (max - min)); @@ -182,7 +182,7 @@ namespace RGB.NET.Core hue = hue * 60.0; hue = hue.Wrap(0, 360); - double saturation = (max == 0) ? 0 : 1.0 - (min / max); + double saturation = max.EqualsInTolerance(0) ? 0 : 1.0 - (min / max); double value = Math.Max(r, Math.Max(g, b)); return (hue, saturation, value); diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs index 2aa3b74..bacc9c0 100644 --- a/RGB.NET.Core/Color/RGBColor.cs +++ b/RGB.NET.Core/Color/RGBColor.cs @@ -6,13 +6,49 @@ namespace RGB.NET.Core { #region Getter + /// + /// Gets the A component value of this as byte in the range [0..255]. + /// + /// + /// + public static byte GetA(this Color color) => color.A.GetByteValueFromPercentage(); + + /// + /// Gets the R component value of this as byte in the range [0..255]. + /// + /// + /// + public static byte GetR(this Color color) => color.R.GetByteValueFromPercentage(); + + /// + /// Gets the G component value of this as byte in the range [0..255]. + /// + /// + /// + public static byte GetG(this Color color) => color.G.GetByteValueFromPercentage(); + + /// + /// Gets the B component value of this as byte in the range [0..255]. + /// + /// + /// + public static byte GetB(this Color color) => color.B.GetByteValueFromPercentage(); + + /// + /// Gets the A, R, G and B component value of this as byte in the range [0..255]. + /// + /// + /// + public static (byte a, byte r, byte g, byte b) GetRGBBytes(this Color color) + => (color.GetA(), color.GetR(), color.GetG(), color.GetB()); + /// /// Gets the A, R, G and B component value of this as percentage in the range [0..1]. /// /// /// - public static (double a, double r, double g, double b) GetRGBPercent(this Color color) - => (color.APercent, color.RPercent, color.GPercent, color.BPercent); + public static (double a, double r, double g, double b) GetRGB(this Color color) + => (color.A, color.R, color.G, color.B); #endregion @@ -28,7 +64,7 @@ namespace RGB.NET.Core /// The blue value to add. /// The new color after the modification. public static Color AddRGB(this Color color, int r = 0, int g = 0, int b = 0) - => new Color(color.APercent, color.R + r, color.G + g, color.B + b); + => new Color(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b); /// /// Adds the given RGB-percent values to this color. @@ -38,7 +74,7 @@ namespace RGB.NET.Core /// The blue value to add. /// The new color after the modification. public static Color AddRGB(this Color color, double r = 0, double g = 0, double b = 0) - => new Color(color.APercent, color.RPercent + r, color.GPercent + g, color.BPercent + b); + => new Color(color.A, color.R + r, color.G + g, color.B + b); /// /// Adds the given alpha value to this color. @@ -46,7 +82,7 @@ namespace RGB.NET.Core /// The alpha value to add. /// The new color after the modification. public static Color AddA(this Color color, int a) - => new Color(color.A + a, color.RPercent, color.GPercent, color.BPercent); + => new Color(color.GetA() + a, color.R, color.G, color.B); /// /// Adds the given alpha-percent value to this color. @@ -54,7 +90,7 @@ namespace RGB.NET.Core /// The alpha value to add. /// The new color after the modification. public static Color AddA(this Color color, double a) - => new Color(color.APercent + a, color.RPercent, color.GPercent, color.BPercent); + => new Color(color.A + a, color.R, color.G, color.B); #endregion @@ -68,7 +104,7 @@ namespace RGB.NET.Core /// The blue value to subtract. /// The new color after the modification. public static Color SubtractRGB(this Color color, int r = 0, int g = 0, int b = 0) - => new Color(color.APercent, color.R - r, color.G - g, color.B - b); + => new Color(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b); /// /// Subtracts the given RGB values to this color. @@ -78,7 +114,7 @@ namespace RGB.NET.Core /// The blue value to subtract. /// The new color after the modification. public static Color SubtractRGB(this Color color, double r = 0, double g = 0, double b = 0) - => new Color(color.APercent, color.RPercent - r, color.GPercent - g, color.BPercent - b); + => new Color(color.A, color.R - r, color.G - g, color.B - b); /// /// Subtracts the given alpha value to this color. @@ -86,7 +122,7 @@ namespace RGB.NET.Core /// The alpha value to subtract. /// The new color after the modification. public static Color SubtractA(this Color color, int a) - => new Color(color.A - a, color.RPercent, color.GPercent, color.BPercent); + => new Color(color.GetA() - a, color.R, color.G, color.B); /// /// Subtracts the given alpha-percent value to this color. @@ -94,7 +130,7 @@ namespace RGB.NET.Core /// The alpha value to subtract. /// The new color after the modification. public static Color SubtractA(this Color color, double aPercent) - => new Color(color.APercent - aPercent, color.RPercent, color.GPercent, color.BPercent); + => new Color(color.A - aPercent, color.R, color.G, color.B); #endregion @@ -108,7 +144,7 @@ namespace RGB.NET.Core /// The blue value to multiply. /// The new color after the modification. public static Color MultiplyRGB(this Color color, double r = 1, double g = 1, double b = 1) - => new Color(color.APercent, color.RPercent * r, color.GPercent * g, color.BPercent * b); + => new Color(color.A, color.R * r, color.G * g, color.B * b); /// /// Multiplies the given alpha value to this color. @@ -116,7 +152,7 @@ namespace RGB.NET.Core /// The alpha value to multiply. /// The new color after the modification. public static Color MultiplyA(this Color color, double a) - => new Color(color.APercent * a, color.RPercent, color.GPercent, color.BPercent); + => new Color(color.A * a, color.R, color.G, color.B); #endregion @@ -130,7 +166,7 @@ namespace RGB.NET.Core /// The blue value to divide. /// The new color after the modification. public static Color DivideRGB(this Color color, double r = 1, double g = 1, double b = 1) - => new Color(color.APercent, color.RPercent / r, color.GPercent / g, color.BPercent / b); + => new Color(color.A, color.R / r, color.G / g, color.B / b); /// /// Divides the given alpha value to this color. @@ -138,7 +174,7 @@ namespace RGB.NET.Core /// The alpha value to divide. /// The new color after the modification. public static Color DivideA(this Color color, double a) - => new Color(color.APercent / a, color.RPercent, color.GPercent, color.BPercent); + => new Color(color.A / a, color.R, color.G, color.B); #endregion @@ -152,7 +188,7 @@ namespace RGB.NET.Core /// The blue value to set. /// The new color after the modification. public static Color SetRGB(this Color color, byte? r = null, byte? g = null, byte? b = null) - => new Color(color.APercent, r ?? color.R, g ?? color.G, b ?? color.B); + => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); /// /// Sets the given RGB value of this color. @@ -162,7 +198,7 @@ namespace RGB.NET.Core /// The blue value to set. /// The new color after the modification. public static Color SetRGB(this Color color, int? r = null, int? g = null, int? b = null) - => new Color(color.APercent, r ?? color.R, g ?? color.G, b ?? color.B); + => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); /// /// Sets the given RGB value of this color. @@ -172,21 +208,21 @@ namespace RGB.NET.Core /// The blue value to set. /// The new color after the modification. public static Color SetRGB(this Color color, double? r = null, double? g = null, double? b = null) - => new Color(color.APercent, r ?? color.RPercent, g ?? color.GPercent, b ?? color.BPercent); + => new Color(color.A, r ?? color.R, g ?? color.G, b ?? color.B); /// /// Sets the given alpha value of this color. /// /// The alpha value to set. /// The new color after the modification. - public static Color SetA(this Color color, int a) => new Color(a, color.RPercent, color.GPercent, color.BPercent); + public static Color SetA(this Color color, int a) => new Color(a, color.R, color.G, color.B); /// /// Sets the given alpha value of this color. /// /// The alpha value to set. /// The new color after the modification. - public static Color SetA(this Color color, double a) => new Color(a, color.RPercent, color.GPercent, color.BPercent); + public static Color SetA(this Color color, double a) => new Color(a, color.R, color.G, color.B); #endregion @@ -198,13 +234,13 @@ namespace RGB.NET.Core /// Gets the current color as a RGB-HEX-string. /// /// The RGB-HEX-string. - public static string AsRGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.R, color.G, color.B); + public static string AsRGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetR(), color.GetG(), color.GetB()); /// /// Gets the current color as a ARGB-HEX-string. /// /// The ARGB-HEX-string. - public static string AsARGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.A, color.R, color.G, color.B); + public static string AsARGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetA(), color.GetR(), color.GetG(), color.GetB()); #endregion diff --git a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs index e6d4a6a..28fa936 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs @@ -57,9 +57,9 @@ namespace RGB.NET.Devices.Asus foreach (KeyValuePair data in dataSet) { int index = ((int)data.Key) * 3; - ColorData[index] = data.Value.R; - ColorData[index + 1] = data.Value.B; - ColorData[index + 2] = data.Value.G; + ColorData[index] = data.Value.GetR(); + ColorData[index + 1] = data.Value.GetB(); + ColorData[index + 2] = data.Value.GetG(); } _updateAction(_handle, ColorData); diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs index 045b6e4..ecc4cd6 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs @@ -39,7 +39,7 @@ namespace RGB.NET.Devices.CoolerMaster foreach (KeyValuePair data in dataSet) { (int row, int column) = ((int, int))data.Key; - _CoolerMasterSDK.SetLedColor(row, column, data.Value.R, data.Value.G, data.Value.B, _deviceIndex); + _CoolerMasterSDK.SetLedColor(row, column, data.Value.GetR(), data.Value.GetG(), data.Value.GetB(), _deviceIndex); } _CoolerMasterSDK.RefreshLed(false, _deviceIndex); diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs index 9540018..664a6e6 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs @@ -46,9 +46,9 @@ namespace RGB.NET.Devices.Corsair _CorsairLedColor color = new _CorsairLedColor { ledId = (int)data.Key, - r = data.Value.R, - g = data.Value.G, - b = data.Value.B + r = data.Value.GetR(), + g = data.Value.GetG(), + b = data.Value.GetB() }; Marshal.StructureToPtr(color, addPtr, false); diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs index 23e1b69..8ea4c6a 100644 --- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs @@ -32,9 +32,9 @@ namespace RGB.NET.Devices.Logitech Color color = dataSet.Values.First(); _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB); - _LogitechGSDK.LogiLedSetLighting((int)Math.Round(color.RPercent * 100), - (int)Math.Round(color.GPercent * 100), - (int)Math.Round(color.BPercent * 100)); + _LogitechGSDK.LogiLedSetLighting((int)Math.Round(color.R * 100), + (int)Math.Round(color.G * 100), + (int)Math.Round(color.B * 100)); } #endregion diff --git a/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs b/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs index cfb5cd9..9bd9a6e 100644 --- a/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs +++ b/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs @@ -158,10 +158,10 @@ namespace RGB.NET.Devices.Logitech [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetColor(byte[] bitmap, int offset, Color color) { - bitmap[offset] = color.B; - bitmap[offset + 1] = color.G; - bitmap[offset + 2] = color.R; - bitmap[offset + 3] = color.A; + bitmap[offset] = color.GetB(); + bitmap[offset + 1] = color.GetG(); + bitmap[offset + 2] = color.GetR(); + bitmap[offset + 3] = color.GetA(); } #endregion diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs index 02f7dd0..a166a3a 100644 --- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs @@ -51,9 +51,9 @@ namespace RGB.NET.Devices.Logitech } else _LogitechGSDK.LogiLedSetLightingForKeyWithKeyName((int)customData, - (int)Math.Round(data.Value.RPercent * 100), - (int)Math.Round(data.Value.GPercent * 100), - (int)Math.Round(data.Value.BPercent * 100)); + (int)Math.Round(data.Value.R * 100), + (int)Math.Round(data.Value.G * 100), + (int)Math.Round(data.Value.B * 100)); } if (usesBitmap) diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs index ab0062c..a95ca98 100644 --- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs @@ -56,9 +56,9 @@ namespace RGB.NET.Devices.Logitech { int zone = (int)data.Key; _LogitechGSDK.LogiLedSetLightingForTargetZone(_deviceType, zone, - (int)Math.Round(data.Value.RPercent * 100), - (int)Math.Round(data.Value.GPercent * 100), - (int)Math.Round(data.Value.BPercent * 100)); + (int)Math.Round(data.Value.R * 100), + (int)Math.Round(data.Value.G * 100), + (int)Math.Round(data.Value.B * 100)); } } diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index 2387690..5fe18ab 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -66,7 +66,7 @@ namespace RGB.NET.Devices.Msi { string deviceType = DeviceInfo.MsiDeviceType; foreach (Led led in leds) - _MsiSDK.SetLedColor(deviceType, (int)led.CustomData, led.Color.R, led.Color.G, led.Color.B); + _MsiSDK.SetLedColor(deviceType, (int)led.CustomData, led.Color.GetR(), led.Color.GetG(), led.Color.GetB()); } } diff --git a/RGB.NET.Devices.Razer/Native/_Color.cs b/RGB.NET.Devices.Razer/Native/_Color.cs index 66b07ea..a36cc78 100644 --- a/RGB.NET.Devices.Razer/Native/_Color.cs +++ b/RGB.NET.Devices.Razer/Native/_Color.cs @@ -21,7 +21,7 @@ namespace RGB.NET.Devices.Razer.Native #region Constructors public _Color(Color color) - : this(color.R, color.G, color.B) { } + : this(color.GetR(), color.GetG(), color.GetB()) { } public _Color(byte red, byte green, byte blue) : this() diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs index 696f54e..e9fea46 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs @@ -62,7 +62,7 @@ namespace RGB.NET.Devices.WS281X.Arduino dataBuffer[0] = (byte)((channel << 4) | UPDATE_COMMAND[0]); int i = 1; foreach ((byte _, byte r, byte g, byte b) in channelData.OrderBy(x => x.Item1.key) - .Select(x => x.Value)) + .Select(x => x.Value.GetRGBBytes())) { dataBuffer[i++] = r; dataBuffer[i++] = g; diff --git a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs index 8146006..20b17a1 100644 --- a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs @@ -12,10 +12,10 @@ namespace RGB.NET.Core.Tests.Color { Core.Color transparent = Core.Color.Transparent; - Assert.AreEqual(0, transparent.A, "A is not 0"); - Assert.AreEqual(0, transparent.R, "R is not 0"); - Assert.AreEqual(0, transparent.G, "G is not 0"); - Assert.AreEqual(0, transparent.B, "B is not 0"); + Assert.AreEqual(0, transparent.GetA(), "A is not 0"); + Assert.AreEqual(0, transparent.GetR(), "R is not 0"); + Assert.AreEqual(0, transparent.GetG(), "G is not 0"); + Assert.AreEqual(0, transparent.GetB(), "B is not 0"); } [TestMethod] @@ -143,10 +143,10 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color = new Core.Color((byte)10, (byte)120, (byte)255); - Assert.AreEqual(255, color.A, "A is not 255"); - Assert.AreEqual(10, color.R, "R is not 10"); - Assert.AreEqual(120, color.G, "G is not 120"); - Assert.AreEqual(255, color.B, "B is not 255"); + Assert.AreEqual(255, color.GetA(), "A is not 255"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); } [TestMethod] @@ -154,10 +154,10 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color = new Core.Color((byte)200, (byte)10, (byte)120, (byte)255); - Assert.AreEqual(200, color.A, "A is not 200"); - Assert.AreEqual(10, color.R, "R is not 10"); - Assert.AreEqual(120, color.G, "G is not 120"); - Assert.AreEqual(255, color.B, "B is not 255"); + Assert.AreEqual(200, color.GetA(), "A is not 200"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); } [TestMethod] @@ -165,10 +165,10 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color = new Core.Color(10, 120, 255); - Assert.AreEqual(255, color.A, "A is not 255"); - Assert.AreEqual(10, color.R, "R is not 10"); - Assert.AreEqual(120, color.G, "G is not 120"); - Assert.AreEqual(255, color.B, "B is not 255"); + Assert.AreEqual(255, color.GetA(), "A is not 255"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); } [TestMethod] @@ -176,10 +176,10 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color = new Core.Color(200, 10, 120, 255); - Assert.AreEqual(200, color.A, "A is not 200"); - Assert.AreEqual(10, color.R, "R is not 10"); - Assert.AreEqual(120, color.G, "G is not 120"); - Assert.AreEqual(255, color.B, "B is not 255"); + Assert.AreEqual(200, color.GetA(), "A is not 200"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); } [TestMethod] @@ -187,17 +187,17 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color1 = new Core.Color(256, 256, 256); - Assert.AreEqual(255, color1.A, "A is not 255"); - Assert.AreEqual(255, color1.R, "R is not 255"); - Assert.AreEqual(255, color1.G, "G is not 255"); - Assert.AreEqual(255, color1.B, "B is not 255"); + Assert.AreEqual(255, color1.GetA(), "A is not 255"); + Assert.AreEqual(255, color1.GetR(), "R is not 255"); + Assert.AreEqual(255, color1.GetG(), "G is not 255"); + Assert.AreEqual(255, color1.GetB(), "B is not 255"); Core.Color color2 = new Core.Color(-1, -1, -1); - Assert.AreEqual(255, color2.A, "A is not 255"); - Assert.AreEqual(0, color2.R, "R is not 0"); - Assert.AreEqual(0, color2.G, "G is not 0"); - Assert.AreEqual(0, color2.B, "B is not 0"); + Assert.AreEqual(255, color2.GetA(), "A is not 255"); + Assert.AreEqual(0, color2.GetR(), "R is not 0"); + Assert.AreEqual(0, color2.GetG(), "G is not 0"); + Assert.AreEqual(0, color2.GetB(), "B is not 0"); } [TestMethod] @@ -205,87 +205,87 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color = new Core.Color(256, 256, 256, 256); - Assert.AreEqual(255, color.A, "A is not 255"); - Assert.AreEqual(255, color.R, "R is not 255"); - Assert.AreEqual(255, color.G, "G is not 255"); - Assert.AreEqual(255, color.B, "B is not 255"); + Assert.AreEqual(255, color.GetA(), "A is not 255"); + Assert.AreEqual(255, color.GetR(), "R is not 255"); + Assert.AreEqual(255, color.GetG(), "G is not 255"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); Core.Color color2 = new Core.Color(-1, -1, -1, -1); + Assert.AreEqual(0, color2.GetA(), "A is not 0"); + Assert.AreEqual(0, color2.GetR(), "R is not 0"); + Assert.AreEqual(0, color2.GetG(), "G is not 0"); + Assert.AreEqual(0, color2.GetB(), "B is not 0"); + } + + [TestMethod] + public void RGBPercentConstructorTest() + { + Core.Color color = new Core.Color(0.25341, 0.55367, 1); + + Assert.AreEqual(1, color.A, DoubleExtensions.TOLERANCE, "A is not 1"); + Assert.AreEqual(0.25341, color.R, DoubleExtensions.TOLERANCE, "R is not 0.25341"); + Assert.AreEqual(0.55367, color.G, DoubleExtensions.TOLERANCE, "G is not 0.55367"); + Assert.AreEqual(1, color.B, DoubleExtensions.TOLERANCE, "B is not 1"); + } + + [TestMethod] + public void ARGBPercentConstructorTest() + { + Core.Color color = new Core.Color(0.3315, 0.25341, 0.55367, 1); + + Assert.AreEqual(0.3315, color.A, DoubleExtensions.TOLERANCE, "A is not 0.3315"); + Assert.AreEqual(0.25341, color.R, DoubleExtensions.TOLERANCE, "R is not 0.25341"); + Assert.AreEqual(0.55367, color.G, DoubleExtensions.TOLERANCE, "G is not 0.55367"); + Assert.AreEqual(1, color.B, DoubleExtensions.TOLERANCE, "B is not 1"); + } + + [TestMethod] + public void RGBPercentConstructorClampTest() + { + Core.Color color1 = new Core.Color(1.1, 1.1, 1.1); + + Assert.AreEqual(1, color1.A, "A is not 1"); + Assert.AreEqual(1, color1.R, "R is not 1"); + Assert.AreEqual(1, color1.G, "G is not 1"); + Assert.AreEqual(1, color1.B, "B is not 1"); + + Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0); + + Assert.AreEqual(1, color2.A, "A is not 1"); + Assert.AreEqual(0, color2.R, "R is not 0"); + Assert.AreEqual(0, color2.G, "G is not 0"); + Assert.AreEqual(0, color2.B, "B is not 0"); + } + + [TestMethod] + public void ARGBPercentConstructorClampTest() + { + Core.Color color1 = new Core.Color(1.1, 1.1, 1.1, 1.1); + + Assert.AreEqual(1, color1.A, "A is not 1"); + Assert.AreEqual(1, color1.R, "R is not 1"); + Assert.AreEqual(1, color1.G, "G is not 1"); + Assert.AreEqual(1, color1.B, "B is not 1"); + + Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0, -1.0); + Assert.AreEqual(0, color2.A, "A is not 0"); Assert.AreEqual(0, color2.R, "R is not 0"); Assert.AreEqual(0, color2.G, "G is not 0"); Assert.AreEqual(0, color2.B, "B is not 0"); } - [TestMethod] - public void RGBPercentConstructorTest() - { - Core.Color color = new Core.Color(0.25341, 0.55367, 1); - - Assert.AreEqual(1, color.APercent, DoubleExtensions.TOLERANCE, "A is not 1"); - Assert.AreEqual(0.25341, color.RPercent, DoubleExtensions.TOLERANCE, "R is not 0.25341"); - Assert.AreEqual(0.55367, color.GPercent, DoubleExtensions.TOLERANCE, "G is not 0.55367"); - Assert.AreEqual(1, color.BPercent, DoubleExtensions.TOLERANCE, "B is not 1"); - } - - [TestMethod] - public void ARGBPercentConstructorTest() - { - Core.Color color = new Core.Color(0.3315, 0.25341, 0.55367, 1); - - Assert.AreEqual(0.3315, color.APercent, DoubleExtensions.TOLERANCE, "A is not 0.3315"); - Assert.AreEqual(0.25341, color.RPercent, DoubleExtensions.TOLERANCE, "R is not 0.25341"); - Assert.AreEqual(0.55367, color.GPercent, DoubleExtensions.TOLERANCE, "G is not 0.55367"); - Assert.AreEqual(1, color.BPercent, DoubleExtensions.TOLERANCE, "B is not 1"); - } - - [TestMethod] - public void RGBPercentConstructorClampTest() - { - Core.Color color1 = new Core.Color(1.1, 1.1, 1.1); - - Assert.AreEqual(1, color1.APercent, "A is not 1"); - Assert.AreEqual(1, color1.RPercent, "R is not 1"); - Assert.AreEqual(1, color1.GPercent, "G is not 1"); - Assert.AreEqual(1, color1.BPercent, "B is not 1"); - - Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0); - - Assert.AreEqual(1, color2.APercent, "A is not 1"); - Assert.AreEqual(0, color2.RPercent, "R is not 0"); - Assert.AreEqual(0, color2.GPercent, "G is not 0"); - Assert.AreEqual(0, color2.BPercent, "B is not 0"); - } - - [TestMethod] - public void ARGBPercentConstructorClampTest() - { - Core.Color color1 = new Core.Color(1.1, 1.1, 1.1, 1.1); - - Assert.AreEqual(1, color1.APercent, "A is not 1"); - Assert.AreEqual(1, color1.RPercent, "R is not 1"); - Assert.AreEqual(1, color1.GPercent, "G is not 1"); - Assert.AreEqual(1, color1.BPercent, "B is not 1"); - - Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0, -1.0); - - Assert.AreEqual(0, color2.APercent, "A is not 0"); - Assert.AreEqual(0, color2.RPercent, "R is not 0"); - Assert.AreEqual(0, color2.GPercent, "G is not 0"); - Assert.AreEqual(0, color2.BPercent, "B is not 0"); - } - [TestMethod] public void CloneConstructorTest() { Core.Color referennceColor = new Core.Color(200, 10, 120, 255); Core.Color color = new Core.Color(referennceColor); - Assert.AreEqual(200, color.A, "A is not 200"); - Assert.AreEqual(10, color.R, "R is not 10"); - Assert.AreEqual(120, color.G, "G is not 120"); - Assert.AreEqual(255, color.B, "B is not 255"); + Assert.AreEqual(200, color.GetA(), "A is not 200"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); } #endregion @@ -297,16 +297,16 @@ namespace RGB.NET.Core.Tests.Color { Core.Color color = (255, 120, 13, 1); - Assert.AreEqual(255, color.A, $"A doesn't equal the used component. ({color.A} != 255)"); - Assert.AreEqual(120, color.R, $"R doesn't equal the used component. ({color.R} != 120)"); - Assert.AreEqual(13, color.G, $"G doesn't equal the used component. ({color.G} != 13)"); - Assert.AreEqual(1, color.B, $"B doesn't equal the used component. ({color.B} != 1)"); + Assert.AreEqual(255, color.GetA(), $"A doesn't equal the used component. ({color.GetA()} != 255)"); + Assert.AreEqual(120, color.GetR(), $"R doesn't equal the used component. ({color.GetR()} != 120)"); + Assert.AreEqual(13, color.GetG(), $"G doesn't equal the used component. ({color.GetG()} != 13)"); + Assert.AreEqual(1, color.GetB(), $"B doesn't equal the used component. ({color.GetB()} != 1)"); } [TestMethod] public void DesconstructTest() { - (byte a, byte r, byte g, byte b) = new Core.Color(255, 120, 13, 1); + (byte a, byte r, byte g, byte b) = new Core.Color(255, 120, 13, 1).GetRGBBytes(); Assert.AreEqual(255, a, $"A doesn't equal the color. ({a} != 255)"); Assert.AreEqual(120, r, $"R doesn't equal the color. ({r} != 120)"); @@ -318,76 +318,76 @@ namespace RGB.NET.Core.Tests.Color public void AToPercentTest() { Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.APercent); + Assert.AreEqual(0, color1.A); Core.Color color2 = new Core.Color(255, 0, 0, 0); - Assert.AreEqual(1, color2.APercent); + Assert.AreEqual(1, color2.A); Core.Color color3 = new Core.Color(128, 0, 0, 0); - Assert.AreEqual(128 / 255.0, color3.APercent); + Assert.AreEqual(128 / 255.0, color3.A); Core.Color color4 = new Core.Color(30, 0, 0, 0); - Assert.AreEqual(30 / 255.0, color4.APercent); + Assert.AreEqual(30 / 255.0, color4.A); Core.Color color5 = new Core.Color(201, 0, 0, 0); - Assert.AreEqual(201 / 255.0, color5.APercent); + Assert.AreEqual(201 / 255.0, color5.A); } [TestMethod] public void RToPercentTest() { Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.RPercent); + Assert.AreEqual(0, color1.R); Core.Color color2 = new Core.Color(0, 255, 0, 0); - Assert.AreEqual(1, color2.RPercent); + Assert.AreEqual(1, color2.R); Core.Color color3 = new Core.Color(0, 128, 0, 0); - Assert.AreEqual(128 / 255.0, color3.RPercent); + Assert.AreEqual(128 / 255.0, color3.R); Core.Color color4 = new Core.Color(0, 30, 0, 0); - Assert.AreEqual(30 / 255.0, color4.RPercent); + Assert.AreEqual(30 / 255.0, color4.R); Core.Color color5 = new Core.Color(0, 201, 0, 0); - Assert.AreEqual(201 / 255.0, color5.RPercent); + Assert.AreEqual(201 / 255.0, color5.R); } [TestMethod] public void GToPercentTest() { Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.GPercent); + Assert.AreEqual(0, color1.G); Core.Color color2 = new Core.Color(0, 0, 255, 0); - Assert.AreEqual(1, color2.GPercent); + Assert.AreEqual(1, color2.G); Core.Color color3 = new Core.Color(0, 0, 128, 0); - Assert.AreEqual(128 / 255.0, color3.GPercent); + Assert.AreEqual(128 / 255.0, color3.G); Core.Color color4 = new Core.Color(0, 0, 30, 0); - Assert.AreEqual(30 / 255.0, color4.GPercent); + Assert.AreEqual(30 / 255.0, color4.G); Core.Color color5 = new Core.Color(0, 0, 201, 0); - Assert.AreEqual(201 / 255.0, color5.GPercent); + Assert.AreEqual(201 / 255.0, color5.G); } [TestMethod] public void BToPercentTest() { Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.BPercent); + Assert.AreEqual(0, color1.B); Core.Color color2 = new Core.Color(0, 0, 0, 255); - Assert.AreEqual(1, color2.BPercent); + Assert.AreEqual(1, color2.B); Core.Color color3 = new Core.Color(0, 0, 0, 128); - Assert.AreEqual(128 / 255.0, color3.BPercent); + Assert.AreEqual(128 / 255.0, color3.B); Core.Color color4 = new Core.Color(0, 0, 0, 30); - Assert.AreEqual(30 / 255.0, color4.BPercent); + Assert.AreEqual(30 / 255.0, color4.B); Core.Color color5 = new Core.Color(0, 0, 0, 201); - Assert.AreEqual(201 / 255.0, color5.BPercent); + Assert.AreEqual(201 / 255.0, color5.B); } #endregion From 5d374db9ef46ac98a812d24a64be621b245de1df Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Mon, 25 Feb 2019 21:25:09 +0100 Subject: [PATCH 7/8] Moved comparison, blending and conversion from color to a behavior-class to make it exchangeable --- .../Color/Behaviors/DefaultColorBehavior.cs | 80 +++++++++++++++++++ .../Color/Behaviors/IColorBehavior.cs | 13 +++ RGB.NET.Core/Color/Color.cs | 61 +++++--------- RGB.NET.Core/RGB.NET.Core.csproj.DotSettings | 1 + 4 files changed, 113 insertions(+), 42 deletions(-) create mode 100644 RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs create mode 100644 RGB.NET.Core/Color/Behaviors/IColorBehavior.cs diff --git a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs new file mode 100644 index 0000000..e666f6f --- /dev/null +++ b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs @@ -0,0 +1,80 @@ +namespace RGB.NET.Core +{ + public class DefaultColorBehavior : IColorBehavior + { + #region Properties & Fields + + private static DefaultColorBehavior _instance = new DefaultColorBehavior(); + /// + /// Gets the singleton instance of . + /// + public static DefaultColorBehavior Instance { get; } = _instance; + + #endregion + + #region Constructors + + private DefaultColorBehavior() + { } + + #endregion + + #region Methods + + /// + /// Converts the individual byte values of this to a human-readable string. + /// + /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". + public virtual string ToString(Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]"; + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public virtual bool Equals(Color color, object obj) + { + if (!(obj is Color)) return false; + + (double a, double r, double g, double b) = ((Color)obj).GetRGB(); + return color.A.EqualsInTolerance(a) && color.R.EqualsInTolerance(r) && color.G.EqualsInTolerance(g) && color.B.EqualsInTolerance(b); + } + + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public virtual int GetHashCode(Color color) + { + unchecked + { + int hashCode = color.A.GetHashCode(); + hashCode = (hashCode * 397) ^ color.R.GetHashCode(); + hashCode = (hashCode * 397) ^ color.G.GetHashCode(); + hashCode = (hashCode * 397) ^ color.B.GetHashCode(); + return hashCode; + } + } + + /// + /// Blends a over this color. + /// + /// The to blend. + public virtual Color Blend(Color baseColor, Color blendColor) + { + if (blendColor.A.EqualsInTolerance(0)) return baseColor; + + if (blendColor.A.EqualsInTolerance(1)) + return blendColor; + + double resultA = (1.0 - ((1.0 - blendColor.A) * (1.0 - baseColor.A))); + double resultR = (((blendColor.R * blendColor.A) / resultA) + ((baseColor.R * baseColor.A * (1.0 - blendColor.A)) / resultA)); + double resultG = (((blendColor.G * blendColor.A) / resultA) + ((baseColor.G * baseColor.A * (1.0 - blendColor.A)) / resultA)); + double resultB = (((blendColor.B * blendColor.A) / resultA) + ((baseColor.B * baseColor.A * (1.0 - blendColor.A)) / resultA)); + + return new Color(resultA, resultR, resultG, resultB); + } + + #endregion + } +} diff --git a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs new file mode 100644 index 0000000..630aca5 --- /dev/null +++ b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs @@ -0,0 +1,13 @@ +namespace RGB.NET.Core +{ + public interface IColorBehavior + { + string ToString(Color color); + + bool Equals(Color color, object obj); + + int GetHashCode(Color color); + + Color Blend(Color baseColor, Color blendColor); + } +} diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs index 0d5a028..81a3a33 100644 --- a/RGB.NET.Core/Color/Color.cs +++ b/RGB.NET.Core/Color/Color.cs @@ -25,6 +25,16 @@ namespace RGB.NET.Core #region Properties & Fields + private static IColorBehavior _behavior = DefaultColorBehavior.Instance; + /// + /// Gets or sets the used to perform operations on colors. + /// + public static IColorBehavior Behavior + { + get => _behavior; + set => _behavior = value ?? DefaultColorBehavior.Instance; + } + /// /// Gets the alpha component value of this as percentage in the range [0..1]. /// @@ -179,62 +189,29 @@ namespace RGB.NET.Core #region Methods /// - /// Converts the individual byte values of this to a human-readable string. + /// Gets a human-readable string, as defined by the current . /// - /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". - public override string ToString() => $"[A: {this.GetA()}, R: {this.GetR()}, G: {this.GetG()}, B: {this.GetB()}]"; + /// A string that contains the individual byte values of this . Default format: "[A: 255, R: 255, G: 0, B: 0]". + public override string ToString() => Behavior.ToString(this); /// - /// Tests whether the specified object is a and is equivalent to this . + /// Tests whether the specified object is a and is equivalent to this , as defined by the current . /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) - { - if (!(obj is Color)) return false; - - (double a, double r, double g, double b) = ((Color)obj).GetRGB(); - return A.EqualsInTolerance(a) && R.EqualsInTolerance(r) && G.EqualsInTolerance(g) && B.EqualsInTolerance(b); - } + public override bool Equals(object obj) => Behavior.Equals(this, obj); /// - /// Returns a hash code for this . + /// Returns a hash code for this , as defined by the current . /// /// An integer value that specifies the hash code for this . - public override int GetHashCode() - { - unchecked - { - int hashCode = A.GetHashCode(); - hashCode = (hashCode * 397) ^ R.GetHashCode(); - hashCode = (hashCode * 397) ^ G.GetHashCode(); - hashCode = (hashCode * 397) ^ B.GetHashCode(); - return hashCode; - } - } - - #region Manipulation + public override int GetHashCode() => Behavior.GetHashCode(this); /// - /// Blends a over this color. + /// Blends a over this color, as defined by the current . /// /// The to blend. - public Color Blend(Color color) - { - if (color.A.EqualsInTolerance(0)) return this; - - if (color.A.EqualsInTolerance(1)) - return color; - - double resultA = (1.0 - ((1.0 - color.A) * (1.0 - A))); - double resultR = (((color.R * color.A) / resultA) + ((R * A * (1.0 - color.A)) / resultA)); - double resultG = (((color.G * color.A) / resultA) + ((G * A * (1.0 - color.A)) / resultA)); - double resultB = (((color.B * color.A) / resultA) + ((B * A * (1.0 - color.A)) / resultA)); - - return new Color(resultA, resultR, resultG, resultB); - } - - #endregion + public Color Blend(Color color) => Behavior.Blend(this, color); #endregion diff --git a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings index 739bd7f..d216495 100644 --- a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings +++ b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings @@ -2,6 +2,7 @@ True True True + True True True True From dabfbdf0a45941edef3d7fc859cd0e1eb4befa0a Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sun, 31 Mar 2019 12:16:07 +0200 Subject: [PATCH 8/8] Small code-issue fixes --- RGB.NET.Core/Color/HSVColor.cs | 7 ++++--- RGB.NET.Core/Color/RGBColor.cs | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs index 21bb5b1..f99581c 100644 --- a/RGB.NET.Core/Color/HSVColor.cs +++ b/RGB.NET.Core/Color/HSVColor.cs @@ -1,4 +1,6 @@ -using System; +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +using System; namespace RGB.NET.Core { @@ -80,8 +82,7 @@ namespace RGB.NET.Core (double cHue, double cSaturation, double cValue) = color.GetHSV(); return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value); } - - + /// /// Divides the given HSV values to this color. /// diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs index bacc9c0..b196076 100644 --- a/RGB.NET.Core/Color/RGBColor.cs +++ b/RGB.NET.Core/Color/RGBColor.cs @@ -1,4 +1,6 @@ -using System; +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +using System; namespace RGB.NET.Core {