将颜色转换为ConsoleColor?

Alo*_*kin 19 c# console colors system.drawing.color

将a转换System.Drawing.Color为类似的最佳方法是什么System.ConsoleColor

Gle*_*den 31

以下是由.NET 4.5转换的控制台颜色十六进制值.首先是该计划:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出.正如您所看到的,报告存在问题DarkYellow.该值的完整32位显示为零.所有其他的alpha通道都有0xFF.

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
Run Code Online (Sandbox Code Playgroud)

编辑:我刚刚得到了更多的东西,所以这里有一个转换器从RGB最接近的ConsoleColor值.请注意,依赖性System.Windows.Media仅适用于演示工具; 实际函数本身只引用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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(部分)......

测试输出


小智 22

public static System.ConsoleColor FromColor(System.Drawing.Color c) {
    int index = (c.R > 128 | c.G > 128 | c.B > 128) ? 8 : 0; // Bright bit
    index |= (c.R > 64) ? 4 : 0; // Red bit
    index |= (c.G > 64) ? 2 : 0; // Green bit
    index |= (c.B > 64) ? 1 : 0; // Blue bit
    return (System.ConsoleColor)index;
}
Run Code Online (Sandbox Code Playgroud)

ConsoleColors枚举似乎使用EGA样式调色板排序,即:

index Brgb
  0   0000  dark black
  1   0001  dark blue
  2   0010  dark green
  3   0011  dark cyan
  4   0100  dark red
  5   0101  dark purple
  6   0110  dark yellow (brown)
  7   0111  dark white (light grey)
  8   1000  bright black (dark grey)
  9   1001  bright blue
 10   1010  bright green
 11   1011  bright cyan    
 12   1100  bright red
 13   1101  bright purple
 14   1110  bright yellow
 15   1111  bright white
Run Code Online (Sandbox Code Playgroud)

您可以将24位颜色(或32位颜色,通过忽略Alpha通道)粗略地映射到具有亮度分量的3位颜色.在这种情况下,如果System.Drawing.Color中的任何一个红色,绿色或蓝色字节大于128,则设置'brightness'位;如果等效源字节大于64,则设置红色,绿色,蓝色位.


Jos*_*osh 14

不幸的是,即使Windows控制台可以支持RGB颜色,Console类也只暴露ConsoleColor枚举,这极大地限制了您可以使用的颜色.如果你想将Color结构映射到"最接近的"ConsoleColor,那将是棘手的.

但是,如果您希望命名的Color与相应的ConsoleColor匹配,您可以制作如下的地图:

var map = new Dictionary<Color, ConsoleColor>();
map[Color.Red] = ConsoleColor.Red;
map[Color.Blue] = ConsoleColor.Blue;
etc...
Run Code Online (Sandbox Code Playgroud)

或者如果性能不那么重要,您可以通过String进行往返.(仅适用于指定颜色)

var color = Enum.Parse(typeof(ConsoleColor), color.Name);
Run Code Online (Sandbox Code Playgroud)

编辑:这是一个关于寻找颜色"亲近"问题的链接.

  • 它确实在Vista及以上.你必须P/Invoke SetConsoleScreenBufferInfoEx(),http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f8fb4005-475d-4edc-99b3-b74519ce5a4e (3认同)