Get the name of the color only with a perfect match:
You can use the KnownColor enumeration to create the lookup you need. See below:
public static class HexColorTranslator
{
private static Dictionary<string, string> _hex2Name;
private static Dictionary<string, string> Hex2Name
{
get
{
if (_hex2Name == null)
{
_hex2Name = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (KnownColor ce in typeof(KnownColor).GetEnumValues())
{
var name = ce.ToString();
var color = Color.FromKnownColor(ce);
var hex = HexConverter(color);
_hex2Name[hex] = name;
}
}
return _hex2Name;
}
}
//https://stackoverflow.com/a/2395708/1155329
private static String HexConverter(System.Drawing.Color c)
{
return c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}
public static string GetKnownColorFromHex(string hex)
{
hex = hex.TrimStart('#');
if (Hex2Name.TryGetValue(hex, out string result)) return result;
return "???";
}
}
Get a color by calling the GetKnownColorFromHex function:
Console.WriteLine(HexColorTranslator.GetKnownColorFromHex("#ff0000")); // Red
Note that unfortunately you cannot use ToKnownColor, unless the Color was created with a known Color. See:
var aquaKnown = Color.FromKnownColor(KnownColor.Aqua);
var aquaUnknown = Color.FromArgb(aquaKnown.A, aquaKnown.R, aquaKnown.G, aquaKnown.B);
Console.WriteLine(aquaKnown.ToKnownColor()); //Aqua
Console.WriteLine(aquaUnknown.ToKnownColor()); //0
Get the name of the nearest color, in RGB space:
If you want to get the closest color, you can try this:
public static string GetNearestKnownColor(string hex)
{
var color = System.Drawing.ColorTranslator.FromHtml(hex);
double bestSquared = double.MaxValue;
KnownColor bestMatch = default(KnownColor);
foreach (KnownColor ce in typeof(KnownColor).GetEnumValues())
{
Color tryColor = Color.FromKnownColor(ce);
double deltaR = tryColor.R - color.R;
double deltaG = tryColor.G - color.G;
double deltaB = tryColor.B - color.B;
double squared = deltaR * deltaR + deltaG * deltaG + deltaB * deltaB;
if(squared == 0) return ce.ToString();
if (squared < bestSquared)
{
bestMatch = ce;
bestSquared = squared;
}
}
return bestMatch.ToString();
}
Note that this is not entirely accurate, as it's operating in RGB space, which may produce results different than a human might categorize colors.