using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; namespace POCs.Sanjay.SharpSnippets.Drawing { public static class ColorExtensions { static Random _randomizer = new Random(); public static Color GetContrast(this Color Source, bool PreserveOpacity) { Color inputColor = Source; //if RGB values are close to each other by a diff less than 10%, then if RGB values are lighter side, decrease the blue by 50% (eventually it will increase in conversion below), if RBB values are on darker side, decrease yellow by about 50% (it will increase in conversion) byte avgColorValue = (byte)((Source.R + Source.G + Source.B) / 3); int diff_r = Math.Abs(Source.R - avgColorValue); int diff_g = Math.Abs(Source.G - avgColorValue); int diff_b = Math.Abs(Source.B - avgColorValue); if (diff_r < 20 && diff_g < 20 && diff_b < 20) //The color is a shade of gray { if (avgColorValue < 123) //color is dark { inputColor = Color.FromArgb(Source.A, 220, 230, 50); } else { inputColor = Color.FromArgb(Source.A, 255, 255, 50); } } byte sourceAlphaValue = Source.A; if (!PreserveOpacity) { sourceAlphaValue = Math.Max(Source.A, (byte)127); //We don't want contrast color to be more than 50% transparent ever. } RGB rgb = new RGB { R = inputColor.R, G = inputColor.G, B = inputColor.B }; HSB hsb = ConvertToHSB(rgb); hsb.H = hsb.H < 180 ? hsb.H + 180 : hsb.H - 180; //_hsb.B = _isColorDark ? 240 : 50; //Added to create dark on light, and light on dark rgb = ConvertToRGB(hsb); return Color.FromArgb((int)sourceAlphaValue, (int)rgb.R, (int)rgb.G, (int)rgb.B); } #region Code from MSDN internal static RGB ConvertToRGB(HSB hsb) { // Following code is taken as it is from MSDN. See link below. // By: Yi-Lun Luo double chroma = hsb.S * hsb.B; double hue2 = hsb.H / 60; double x = chroma * (1 - Math.Abs(hue2 % 2 - 1)); double r1 = 0d; double g1 = 0d; double b1 = 0d; if (hue2 >= 0 && hue2 < 1) { r1 = chroma; g1 = x; } else if (hue2 >= 1 && hue2 < 2) { r1 = x; g1 = chroma; } else if (hue2 >= 2 && hue2 < 3) { g1 = chroma; b1 = x; } else if (hue2 >= 3 && hue2 < 4) { g1 = x; b1 = chroma; } else if (hue2 >= 4 && hue2 < 5) { r1 = x; b1 = chroma; } else if (hue2 >= 5 && hue2 <= 6) { r1 = chroma; b1 = x; } double m = hsb.B - chroma; return new RGB() { R = r1 + m, G = g1 + m, B = b1 + m }; } internal static HSB ConvertToHSB(RGB rgb) { // Following code is taken as it is from MSDN. See link below. // By: Yi-Lun Luo double r = rgb.R; double g = rgb.G; double b = rgb.B; double max = Max(r, g, b); double min = Min(r, g, b); double chroma = max - min; double hue2 = 0d; if (chroma != 0) { if (max == r) { hue2 = (g - b) / chroma; } else if (max == g) { hue2 = (b - r) / chroma + 2; } else { hue2 = (r - g) / chroma + 4; } } double hue = hue2 * 60; if (hue < 0) { hue += 360; } double brightness = max; double saturation = 0; if (chroma != 0) { saturation = chroma / brightness; } return new HSB() { H = hue, S = saturation, B = brightness }; } private static double Max(double d1, double d2, double d3) { if (d1 > d2) { return Math.Max(d1, d3); } return Math.Max(d2, d3); } private static double Min(double d1, double d2, double d3) { if (d1 < d2) { return Math.Min(d1, d3); } return Math.Min(d2, d3); } internal struct RGB { internal double R; internal double G; internal double B; } internal struct HSB { internal double H; internal double S; internal double B; } #endregion //Code from MSDN } }