Converting Color to ConsoleColor?

Alon Gubkin picture Alon Gubkin · Jan 1, 2010 · Viewed 29.5k times · Source

What is the best way to convert a System.Drawing.Color to a similar System.ConsoleColor?

Answer

Glenn Slayden picture Glenn Slayden · Sep 9, 2012

Here are the console color hex values, as converted by .NET 4.5. First the program:

using System;
using System.Drawing;

class Program
{
    static void Main(string[] args)
    {
        foreach (var n in Enum.GetNames(typeof(ConsoleColor)))
            Console.WriteLine("{0,-12} #{1:X6}", n, Color.FromName(n).ToArgb() & 0xFFFFFF);
    }
}

And here's the output. As you can see, there's a problem with the reporting for DarkYellow. The full 32-bits of that one show up as zero. All the others have 0xFF for the alpha channel.

Black        #000000
DarkBlue     #00008B
DarkGreen    #006400
DarkCyan     #008B8B
DarkRed      #8B0000
DarkMagenta  #8B008B
DarkYellow   #000000   <-- see comments
Gray         #808080
DarkGray     #A9A9A9
Blue         #0000FF
Green        #008000
Cyan         #00FFFF
Red          #FF0000
Magenta      #FF00FF
Yellow       #FFFF00
White        #FFFFFF

edit: I got a little more carried away just now, so here's a converter from RGB to the nearest ConsoleColor value. Note that the dependency on System.Windows.Media is only for the demonstration harness; the actual function itself only references System.Drawing.

using System;
using System.Windows.Media;

class NearestConsoleColor
{
    static ConsoleColor ClosestConsoleColor(byte r, byte g, byte b)
    {
        ConsoleColor ret = 0;
        double rr = r, gg = g, bb = b, delta = double.MaxValue;

        foreach (ConsoleColor cc in Enum.GetValues(typeof(ConsoleColor)))
        {
            var n = Enum.GetName(typeof(ConsoleColor), cc);
            var c = System.Drawing.Color.FromName(n == "DarkYellow" ? "Orange" : n); // bug fix
            var t = Math.Pow(c.R - rr, 2.0) + Math.Pow(c.G - gg, 2.0) + Math.Pow(c.B - bb, 2.0);
            if (t == 0.0)
                return cc;
            if (t < delta)
            {
                delta = t;
                ret = cc;
            }
        }
        return ret;
    }

    static void Main()
    {
        foreach (var pi in typeof(Colors).GetProperties())
        {
            var c = (Color)ColorConverter.ConvertFromString(pi.Name);
            var cc = ClosestConsoleColor(c.R, c.G, c.B);

            Console.ForegroundColor = cc;
            Console.WriteLine("{0,-20} {1} {2}", pi.Name, c, Enum.GetName(typeof(ConsoleColor), cc));
        }
    }
}

The output (partial)...

test output