Example #1
0
        private static bool CheckColor(LabColor color, PaletteOptions options)
        {
            var rgb          = color.ToRgb();
            var hcl          = color.ToHcl();
            var compLab      = rgb.ToLab();
            var labTolerance = 7;

            return(
                hcl.H >= options.HueMin &&
                hcl.H <= options.HueMax &&
                hcl.C >= options.ChromaMin &&
                hcl.C <= options.ChromaMax &&
                hcl.L >= options.LightMin &&
                hcl.L <= options.LightMax &&
                compLab.L >= (color.L - labTolerance) &&
                compLab.L <= (color.L + labTolerance) &&
                compLab.A >= (color.A - labTolerance) &&
                compLab.A <= (color.A + labTolerance) &&
                compLab.B >= (color.B - labTolerance) &&
                compLab.B <= (color.B + labTolerance)
                );
        }
Example #2
0
        // WARNING: may return [NaN, NaN, NaN]
        private LabColor Simulate(LabColor lab, ColorDistanceType type, int amount = 1)
        {

            // Cache
            var key = string.Format("{0}-{1}{2}", lab, type, amount);
            if (this.simulateCache.ContainsKey(key))
            {
                return this.simulateCache[key];
            }

            // Get data from type
            var confuse = ConfusionLine.Get(type);

            // Code adapted from http://galacticmilk.com/labs/Color-Vision/Javascript/Color.Vision.Simulate.js
            var color = lab.ToRgb();
            var sr = color.R;
            var sg = color.G;
            var sb = color.B;
            double dr = sr; // destination color
            double dg = sg;
            double db = sb;
            // Convert source color into XYZ color space
            var pow_r = Math.Pow(sr, 2.2);
            var pow_g = Math.Pow(sg, 2.2);
            var pow_b = Math.Pow(sb, 2.2);
            var X = pow_r * 0.412424 + pow_g * 0.357579 + pow_b * 0.180464; // RGB->XYZ (sRGB:D65)
            var Y = pow_r * 0.212656 + pow_g * 0.715158 + pow_b * 0.0721856;
            var Z = pow_r * 0.0193324 + pow_g * 0.119193 + pow_b * 0.950444;
            // Convert XYZ into xyY Chromacity Coordinates (xy) and Luminance (Y)
            var chroma_x = X / (X + Y + Z);
            var chroma_y = Y / (X + Y + Z);
            // Generate the "Confusion Line" between the source color and the Confusion Point
            var m = (chroma_y - confuse.Y) / (chroma_x - confuse.X); // slope of Confusion Line
            var yint = chroma_y - chroma_x * m; // y-intercept of confusion line (x-intercept = 0.0)
                                                // How far the xy coords deviate from the simulation
            var deviate_x = (confuse.Yint - yint) / (m - confuse.M);
            var deviate_y = (m * deviate_x) + yint;
            // Compute the simulated color's XYZ coords
            X = deviate_x * Y / deviate_y;
            Z = (1.0 - (deviate_x + deviate_y)) * Y / deviate_y;
            // Neutral grey calculated from luminance (in D65)
            var neutral_X = 0.312713 * Y / 0.329016;
            var neutral_Z = 0.358271 * Y / 0.329016;
            // Difference between simulated color and neutral grey
            var diff_X = neutral_X - X;
            var diff_Z = neutral_Z - Z;
            var diff_r = diff_X * 3.24071 + diff_Z * -0.498571; // XYZ->RGB (sRGB:D65)
            var diff_g = diff_X * -0.969258 + diff_Z * 0.0415557;
            var diff_b = diff_X * 0.0556352 + diff_Z * 1.05707;
            // Convert to RGB color space
            dr = X * 3.24071 + Y * -1.53726 + Z * -0.498571; // XYZ->RGB (sRGB:D65)
            dg = X * -0.969258 + Y * 1.87599 + Z * 0.0415557;
            db = X * 0.0556352 + Y * -0.203996 + Z * 1.05707;
            // Compensate simulated color towards a neutral fit in RGB space
            var fit_r = ((dr < 0.0 ? 0.0 : 1.0) - dr) / diff_r;
            var fit_g = ((dg < 0.0 ? 0.0 : 1.0) - dg) / diff_g;
            var fit_b = ((db < 0.0 ? 0.0 : 1.0) - db) / diff_b;
            var adjust = Math.Max( // highest value
                Math.Max(
                    (fit_r > 1.0 || fit_r < 0.0) ? 0.0 : fit_r,
                    (fit_g > 1.0 || fit_g < 0.0) ? 0.0 : fit_g),
                (fit_b > 1.0 || fit_b < 0.0) ? 0.0 : fit_b
            );
            // Shift proportional to the greatest shift
            dr = dr + (adjust * diff_r);
            dg = dg + (adjust * diff_g);
            db = db + (adjust * diff_b);
            // Apply gamma correction
            dr = Math.Pow(dr, 1.0 / 2.2);
            dg = Math.Pow(dg, 1.0 / 2.2);
            db = Math.Pow(db, 1.0 / 2.2);
            // Anomylize colors
            dr = sr * (1.0 - amount) + dr * amount;
            dg = sg * (1.0 - amount) + dg * amount;
            db = sb * (1.0 - amount) + db * amount;
            var dcolor = Color.FromArgb(
                (int)Math.Round(dr),
                (int)Math.Round(dg),
                (int)Math.Round(db));
            var result = dcolor.ToLab();
            this.simulateCache[key] = result;
            return result;
        }