示例#1
0
        private Bitmap DrawBitmap(string model)
        {
            var gamut = CIE1931Gamut.ForModel(model);

            int    dimension = 500;
            Bitmap b         = new Bitmap(dimension, dimension);

            for (int x = 0; x < dimension; x++)
            {
                for (int y = 0; y < dimension; y++)
                {
                    CIE1931Point point = new CIE1931Point(x / (dimension * 1.0), y / (dimension * 1.0));
                    var          rgb   = HueColorConverter.XYToRgb(point, model);

                    Color c;
                    if (point.x + point.y > 1.0)
                    {
                        c = Color.Black;
                    }
                    else if (gamut.Contains(point))
                    {
                        c = Color.FromArgb((int)(rgb.R * 255.999), (int)(rgb.G * 255.999), (int)(rgb.B * 255.999));
                    }
                    else
                    {
                        c = Color.FromArgb((int)(rgb.R * 127.999), (int)(rgb.G * 127.999), (int)(rgb.B * 127.999));
                    }

                    // CIE1931 charts are drawn with y-increasing being upwards, not downwards as in bitmaps.
                    b.SetPixel(x, (dimension - 1) - y, c);
                }
            }
            return(b);
        }
示例#2
0
        public void ColorConversionRoundtripAllPoints()
        {
            // Use a consistent seed for test reproducability
            Random r = new Random(0);

            for (int trial = 0; trial < 1000; trial++)
            {
                CIE1931Point originalXy;

                // Randomly generate a test color that is at a valid CIE1931 coordinate.
                do
                {
                    originalXy = new CIE1931Point(r.NextDouble(), r.NextDouble());
                }while (originalXy.x + originalXy.y >= 1.0);

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

                // We expect a point that is both inside the lamp's gamut and the "wide gamut"
                // used for XYZ->RGB and RGB->XYZ conversion.
                // Conversion from XY to RGB
                var expectedXy = CIE1931Gamut.ForModel("LCT001").NearestContainedPoint(originalXy);
                expectedXy = CIE1931Gamut.PhilipsWideGamut.NearestContainedPoint(expectedXy);

                // RGB to XY
                expectedXy = CIE1931Gamut.ForModel("LCT001").NearestContainedPoint(expectedXy);

                AssertAreEqual(expectedXy, xy, 0.0001);
            }
        }
示例#3
0
        public void GamutContainsWorksCorrectly()
        {
            Random r = new Random(0);

            for (int trial = 0; trial < 1000; trial++)
            {
                var point  = new CIE1931Point(r.NextDouble(), r.NextDouble());
                var gamutB = CIE1931Gamut.ForModel("LCT001");

                Assert.AreEqual(ReferenceColorConverter.CheckPointInLampsReach(point), gamutB.Contains(point));
            }
        }
示例#4
0
        public void ColorsOutsideGamutAdjustedToInBeInGamut()
        {
            // This green is in the gamut of LST001, but not LCT001.
            CIE1931Point outsideGreen = new CIE1931Point(0.18, 0.72);

            CIE1931Point gamutAGreen = new CIE1931Point(0.2151, 0.7106);
            CIE1931Point gamutBGreen = new CIE1931Point(0.409, 0.518);
            CIE1931Point gamutCGreen = new CIE1931Point(0.17, 0.7);

            AssertAreEqual(gamutAGreen, CIE1931Gamut.ForModel("LST001").NearestContainedPoint(outsideGreen), 0.0001);
            AssertAreEqual(gamutBGreen, CIE1931Gamut.ForModel("LCT001").NearestContainedPoint(outsideGreen), 0.0001);
            AssertAreEqual(gamutCGreen, CIE1931Gamut.ForModel("LST002").NearestContainedPoint(outsideGreen), 0.0001);
        }
示例#5
0
        public void ColorsOutsideGamutAdjustedToInBeInGamutOnConversion()
        {
            // The green primary of Gamut A.
            CIE1931Point gamutGreen = new CIE1931Point(0.2151, 0.7106);

            // A color green outside Gamut A.
            CIE1931Point greenOutsideGamut = new CIE1931Point(0.21, 0.75);

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

            // Points should be equal, since the green outside the gamut should
            // be adjusted the the nearest green in-gamut.
            Assert.AreEqual(a.R, b.R);
            Assert.AreEqual(a.G, b.G);
            Assert.AreEqual(a.B, b.B);
        }
示例#6
0
        public void ColorConversionWhitePoint()
        {
            // These light models are capable of Gamuts A, B and C respectively.
            // See http://www.developers.meethue.com/documentation/supported-lights
            string[] models = new string[] { "LST001", "LCT001", "LST002" };

            foreach (string model in models)
            {
                // Make sure that Philips' white point resolves to #FFFFFF for all lights.
                var rgb = HueColorConverter.XYToRgb(CIE1931Point.PhilipsWhite, CIE1931Gamut.ForModel(model));
                Assert.AreEqual(rgb.R, 1.0, 0.0001);
                Assert.AreEqual(rgb.G, 1.0, 0.0001);
                Assert.AreEqual(rgb.B, 1.0, 0.0001);

                var xy = HueColorConverter.RgbToXY(new RGBColor(1.0, 1.0, 1.0), CIE1931Gamut.ForModel(model));
                AssertAreEqual(CIE1931Point.PhilipsWhite, xy, 0.0001);
            }
        }
示例#7
0
        public void ColorConversionRoundtripInsideGamut()
        {
            // Use a consistent seed for test reproducability
            Random r = new Random(0);

            for (int trial = 0; trial < 1000; trial++)
            {
                CIE1931Point originalXy;

                // Randomly generate a test color that is at a valid CIE1931 coordinate.
                do
                {
                    originalXy = new CIE1931Point(r.NextDouble(), r.NextDouble());
                }while (originalXy.x + originalXy.y >= 1.0 ||
                        !ReferenceColorConverter.CheckPointInLampsReach(originalXy) ||
                        !CIE1931Gamut.PhilipsWideGamut.Contains(originalXy));

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

                AssertAreEqual(originalXy, xy, 0.0001);
            }
        }
示例#8
0
        public void CompareColorConversionWithReference()
        {
            // Use a consistent seed for test reproducability
            Random r = new Random(0);

            for (int trial = 0; trial < 1000; trial++)
            {
                double red   = r.NextDouble();
                double green = r.NextDouble();
                double blue  = r.NextDouble();

                var referenceXy = ReferenceColorConverter.XyFromColor(red, green, blue);

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

                AssertAreEqual(referenceXy, actualXy, 0.0001);
            }
        }
示例#9
0
        /// <summary>
        /// Set state on a single light
        /// </summary>
        /// <param name="light"></param>
        /// <param name="xy"></param>
        /// <param name="gamut"></param>
        /// <param name="brightness"></param>
        /// <param name="timeSpan"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static void SetState(this EntertainmentLight light, CancellationToken cancellationToken, CIE1931Point xy, CIE1931Gamut gamut, double?brightness = null, TimeSpan timeSpan = default(TimeSpan))
        {
            var rgb = HueColorConverter.XYToRgb(xy, gamut);

            //Create a new transition for this light
            Transition transition = new Transition(rgb, brightness, timeSpan);

            light.Transition = transition;

            //Start the transition
            transition.Start(light.State.RGBColor, light.State.Brightness, cancellationToken);
        }
示例#10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="light"></param>
        /// <param name="xy"></param>
        /// <param name="gamut">The gamut to use</param>
        /// <param name="timeSpan"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static void SetColor(this EntertainmentLight light, CancellationToken cancellationToken, CIE1931Point xy, CIE1931Gamut gamut, TimeSpan timeSpan = default)
        {
            var rgb = HueColorConverter.XYToRgb(xy, gamut);

            light.SetState(cancellationToken, rgb, null, timeSpan);
        }