Converting Color to ConsoleColor?

前端 未结 8 1350
面向向阳花
面向向阳花 2020-12-02 21:22

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

8条回答
  •  死守一世寂寞
    2020-12-02 21:28

    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

提交回复
热议问题