There are many answers here already.
In short I support those that propose to use System.Drawing.ColorTranslator.
I get that some people want to avoid System.Windows.Media so there is the other solution, and since you want to have a System.Drawing.Color you should have a reference to System.Drawing already in your project.
So in short: Use the Framework if you can.
A more complete native solution
So, if for some reason you want to avoid System.Drawing.ColorTranslator and create your own implementation, you should at least make it respect the specifications
So this is a solution that does #RGB and #RGBA shorthand - and extended color definition
public static Color ParseHtmlColor(string htmlColor) => Color.FromArgb(HtmlColorToArgb(htmlColor));
public static int HtmlColorToArgb(string htmlColor, bool requireHexSpecified = false, int defaultAlpha = 0xFF)
{
if (string.IsNullOrEmpty(htmlColor))
{
throw new ArgumentNullException(nameof(htmlColor));
}
if (!htmlColor.StartsWith("#") && requireHexSpecified)
{
throw new ArgumentException($"Provided parameter '{htmlColor}' is not valid");
}
htmlColor = htmlColor.TrimStart('#');
// int[] symbols
var symbolCount = htmlColor.Length;
var value = int.Parse(htmlColor, System.Globalization.NumberStyles.HexNumber);
switch (symbolCount)
{
case 3: // RGB short hand
{
return defaultAlpha << 24
| (value & 0xF)
| (value & 0xF) << 4
| (value & 0xF0) << 4
| (value & 0xF0) << 8
| (value & 0xF00) << 8
| (value & 0xF00) << 12
;
}
case 4: // RGBA short hand
{
// Inline alpha swap
return (value & 0xF) << 24
| (value & 0xF) << 28
| (value & 0xF0) >> 4
| (value & 0xF0)
| (value & 0xF00)
| (value & 0xF00) << 4
| (value & 0xF000) << 4
| (value & 0xF000) << 8
;
}
case 6: // RGB complete definition
{
return defaultAlpha << 24 | value;
}
case 8: // RGBA complete definition
{
// Alpha swap
return (value & 0xFF) << 24 | (value >> 8);
}
default:
throw new FormatException("Invalid HTML Color");
}
}
If you for some reason don't want to use System.Globalization I'm sure you'll find a code snipped for parsing hex symbols.
Tests
public static void TestColors()
{
foreach (var testCase in TestCases) TestColor(testCase);
}
static string[] TestCases = new string[] {
"111",
"FFF",
"17A",
"F52",
"444F",
"2348",
"4320",
"121212",
"808080",
"FFFFFF",
"A0E0C0",
"0A070B",
"FFFFFFFF",
"808080FF",
"40807710"
};
public static void TestColor(string htmlColor)
{
Console.Write($" {htmlColor} -> ");
var color = ParseHtmlColor(htmlColor);
Console.WriteLine("0x" + color.ToArgb().ToString("X"));
}
P.S.:
Feel free to remove the paramters, they only intend to show how you could tweak the function to handle format errors and defaults.
P.P.S.:
The error messages are not very descriptive at the moment