public void ToColorTest() { List <Tuple <string, Color?> > tests = new List <Tuple <string, Color?> > { Tuple.Create <string, Color?>("", null), Tuple.Create <string, Color?>("White", Color.White), Tuple.Create <string, Color?>("WHITE", Color.White), Tuple.Create <string, Color?>(" white ", Color.White), Tuple.Create <string, Color?>("#fff", Color.White), Tuple.Create <string, Color?>("fcd", Color.FromArgb(0xff, 0xcc, 0xdd)), Tuple.Create <string, Color?>("ffeedd", Color.FromArgb(0xff, 0xee, 0xdd)), Tuple.Create <string, Color?>("#111111", Color.FromArgb(0x11, 0x11, 0x11)), Tuple.Create <string, Color?>("rgb(1,2,3)", Color.FromArgb(1, 2, 3)), Tuple.Create <string, Color?>("rgb( 1, 2, 3)", Color.FromArgb(1, 2, 3)), Tuple.Create <string, Color?>("rgba(2, 3, 4, 1.0)", Color.FromArgb(255, 2, 3, 4)), Tuple.Create <string, Color?>("hsl(120, 100%, 50%)", ColorExtensions.FromHsl(1.0 / 3.0, 1.0, 0.5)), Tuple.Create <string, Color?>("hsl(360, 10%, 25%)", ColorExtensions.FromHsl(0, .1, .25)), Tuple.Create <string, Color?>("hsla(30, 10%, 25%, 0.5)", ColorExtensions.FromAhsl(0.5, 1.0 / 12.0, .1, .25)), }; foreach (var t in tests) { var expected = t.Item2; var actual = t.Item1.ToColor(); if (!actual.HasValue) { Assert.IsNull(expected, "Color: " + t.Item1); } else { Assert.IsNotNull(expected, "Color: " + t.Item1); Assert.IsTrue(expected.Value.R == actual.Value.R && expected.Value.G == actual.Value.G && expected.Value.B == actual.Value.B, "Color: " + t.Item1); } } }
public static Color?ToColor(this string str, bool htmlSafe = false) { if (string.IsNullOrWhiteSpace(str)) { return(null); } str = str.Trim(); if (str.StartsWith("#")) { str = str.Substring(1); } else if (str.StartsWith("rgb(")) { var parts = str.Substring("rgb(".Length).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 3) { return(null); } int r = parts[0].ToInt32(); int g = parts[1].ToInt32(); int b = parts[2].ToInt32(); if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { return(null); } return(Color.FromArgb(r, g, b)); } else if (str.StartsWith("rgba(")) { var parts = str.Substring("rgba(".Length).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 4) { return(null); } int r = parts[0].ToInt32(); int g = parts[1].ToInt32(); int b = parts[2].ToInt32(); int a = (int)(255 * parts[3].ToDouble()); if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) { return(null); } return(Color.FromArgb(a, r, g, b)); } else if (str.StartsWith("hsl(")) { var parts = str.Substring("hsl(".Length).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 3) { return(null); } double h = parts[0].ToDouble() / 360.0; double s = parts[1].ToDouble(); double l = parts[2].ToDouble(); // h can be any value actually, since it gets converted to 0-360 (wheel of color) if (s < 0 || s > 1 || l < 0 || l > 1) { return(null); } return(ColorExtensions.FromHsl(h, s, l)); } else if (str.StartsWith("hsla(")) { var parts = str.Substring("hsla(".Length).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 4) { return(null); } double h = parts[0].ToDouble() / 360.0; double s = parts[1].ToDouble(); double l = parts[2].ToDouble(); double a = parts[3].ToDouble(); if (s < 0 || s > 1 || l < 0 || l > 1 || a < 0 || a > 1) { return(null); } return(ColorExtensions.FromAhsl(a, h, s, l)); } else { try { var color = Color.FromName(str); if (!(color.R == 0 && color.G == 0 && color.B == 0 && color.A == 0) || string.Compare(str, "black", true) == 0) { return(color); } } catch (Exception) { } if (htmlSafe) { return(null); // must be either a named color or start with #/rgb to be HTML safe } } if (str.Length == 3) { str = string.Concat(str[0], str[0], str[1], str[1], str[2], str[2]); } else if (str.Length != 6) { return(null); } byte[] bytes = str.HexStringToBytes(); if (bytes == null || bytes.Length != 3) { return(null); } return(Color.FromArgb(bytes[0], bytes[1], bytes[2])); }