using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; /// /// 颜色自动生成帮助类 /// public static class ColorHelper { private static readonly Dictionary _colorCache = new Dictionary();//颜色缓存 private static readonly Dictionary _htmlColorCache = new Dictionary();//颜色缓存 /// /// 判断color是否为HtmlColor(HtmlColor格式如#A1B2C3) /// /// /// public static bool IsHtmlColor(string color) { if (!color.StartsWith("#")) return false; if (color.Length != 7) return false; string r = color.Substring(1, 2); string g = color.Substring(3, 2); string b = color.Substring(5, 2); bool r1 = byte.TryParse(r, System.Globalization.NumberStyles.HexNumber, null, out _); bool r2 = byte.TryParse(g, System.Globalization.NumberStyles.HexNumber, null, out _); bool r3 = byte.TryParse(b, System.Globalization.NumberStyles.HexNumber, null, out _); return r1 & r2 & r3; } /// /// 根据key得到一种易识别的颜色,相同的key会得到相同的颜色(若要使多个key得到的颜色具有高对比度,请先调用GenerateColor) /// /// /// public static Color GetColor(string key) { if (key == null) key = ""; if (_colorCache.ContainsKey(key)) return _colorCache[key]; Random random = new Random(key.GetHashCode()); var H = random.Next(0, 360);//色调 var S = random.NextDouble();//饱和度 var L = random.NextDouble();//亮度 S = 0.7 + S * 0.2; // [0.7 - 0.9] 排除过灰颜色 L = 0.4 + L * 0.4; // [0.4 - 0.8] 排除过亮过暗色 byte r, g, b; if (S == 0) { r = g = b = (byte)(L * 255); } else { double v1, v2; double hue = H / 360d; v2 = (L < 0.5) ? (L * (1 + S)) : ((L + S) - (L * S)); v1 = 2 * L - v2; r = (byte)(255 * HueToRGB(v1, v2, hue + (1.0f / 3))); g = (byte)(255 * HueToRGB(v1, v2, hue)); b = (byte)(255 * HueToRGB(v1, v2, hue - (1.0f / 3))); } var color = Color.FromArgb(r, g, b); var rgbhtml = ColorTranslator.ToHtml(color); if (!_colorCache.ContainsKey(key)) _colorCache.Add(key, color); if (!_htmlColorCache.ContainsKey(key)) _htmlColorCache.Add(key, rgbhtml); return color; } /// /// 根据key得到一种易识别的颜色,相同的key会得到相同的颜色(若要使多个key得到的颜色具有高对比度,请先调用GenerateColor) /// /// /// public static string GetHtmlColor(string key) { if (key == null) key = ""; if (_htmlColorCache.ContainsKey(key)) return _htmlColorCache[key]; string rgbhtml = ColorTranslator.ToHtml(GetColor(key)); return rgbhtml; } /// /// 提前生成多个易识别且不相近的颜色,生成后通过GetColor或CetHtmlColor获取 /// /// 所有颜色对应的key,个数超过360时效果不佳 /// public static void GenerateColor(IEnumerable keys) { _colorCache.Clear(); _htmlColorCache.Clear(); keys = keys.Distinct(); int idx = 0; List<(int H, double S, double L)> list = new List<(int H, double S, double L)>(); int count = keys.Count(); int value = 360 / count; if (value == 0) value = 1; foreach (var key in keys) { Random random = new Random(key.GetHashCode()); int H = random.Next(idx * value, (idx + 1) * value);//色调 H %= 360; double S = random.NextDouble();//饱和度 double L = random.NextDouble();//亮度 S = 0.7 + S * 0.2; // [0.7 - 0.9] 排除过灰颜色 L = 0.4 + L * 0.4; // [0.4 - 0.8] 排除过亮过暗色 byte r, g, b; if (S == 0) { r = g = b = (byte)(L * 255); } else { double v1, v2; double hue = H / 360d; v2 = (L < 0.5) ? (L * (1 + S)) : ((L + S) - (L * S)); v1 = 2 * L - v2; r = (byte)(255 * HueToRGB(v1, v2, hue + (1.0f / 3))); g = (byte)(255 * HueToRGB(v1, v2, hue)); b = (byte)(255 * HueToRGB(v1, v2, hue - (1.0f / 3))); } list.Add((H, S, L)); var color = Color.FromArgb(r, g, b); var rgbhtml = ColorTranslator.ToHtml(color); if (!_colorCache.ContainsKey(key)) _colorCache.Add(key, color); else _colorCache[key] = color; if (!_htmlColorCache.ContainsKey(key)) _htmlColorCache.Add(key, rgbhtml); else _htmlColorCache[key] = rgbhtml; idx++; } } private static double HueToRGB(double v1, double v2, double vH) { if (vH < 0) vH += 1; if (vH > 1) vH -= 1; if ((6 * vH) < 1) return (v1 + (v2 - v1) * 6 * vH); if ((2 * vH) < 1) return v2; if ((3 * vH) < 2) return (v1 + (v2 - v1) * ((2.0f / 3) - vH) * 6); return v1; } }