将System.Drawing.Color
转换为类似System.ConsoleColor
的最佳方法是什么?将颜色转换为ConsoleColor?
回答
不幸的是,尽管Windows控制台可以支持RGB颜色,但Console类只公开了ConsoleColor枚举,这大大限制了您可以使用的可能颜色。如果你想要一个Color结构映射到“最接近的”ConsoleColor,那将是棘手的。
但是如果你想指定的颜色,以配合相应的ConsoleColor你可以做一个地图,如:
var map = new Dictionary<Color, ConsoleColor>();
map[Color.Red] = ConsoleColor.Red;
map[Color.Blue] = ConsoleColor.Blue;
etc...
或者,如果表现并不重要,你可以通过字符串往返。 (仅适用于命名颜色)
var color = Enum.Parse(typeof(ConsoleColor), color.Name);
编辑:这里有一个question about finding color "closeness"的链接。
是否可能没有Console类? – 2010-01-01 15:22:33
不会出现。 SetConsoleTextAttribute Win32 API仅为R,G,B和亮度位定义了4 x 1位标志。这只会支持ConsoleColor枚举所支持的16种颜色。 – Josh 2010-01-01 15:35:36
但是你说Windows控制台支持任何RGB颜色...... – 2010-01-01 15:42:40
在Vista和更高版本上,请参阅SetConsoleScreenBufferInfoEx API函数。
有关使用示例,请参阅my answer与另一个非常类似的StackOverflow问题。 (感谢Hans Passant提供的原始答案)。
以下是由.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);
}
}
这里的输出。正如你所看到的,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
编辑:我有一个小更忘乎所以刚才,所以这里是从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));
}
}
}
输出(局部的)...
上面的DarkYellow十六进制代码(帖子的开头)是错误的。它说#000000,但它应该是#d7c32a(如此处所述=> http://rgb.to/color/6990/dark-yellow) – SuperJMN 2017-01-18 19:00:18
@SuperJMN请注意我在原始文章中的评论:“正如您可以看到,DarkYellow的报告存在问题。“ – 2017-01-19 05:27:39
哦,好的!我没有读到它是一个程序输出。我将这个十六进制值用于我的算法版本,并在向字典中添加值时发现问题:)对不起! – SuperJMN 2017-01-19 09:36:50
一种简单而有效的方法可以通过使用Color
类的,GetBrightness
和GetSaturation
方法来实现。
public static ConsoleColor GetConsoleColor(this Color color) {
if (color.GetSaturation() < 0.5) {
// we have a grayish color
switch ((int)(color.GetBrightness()*3.5)) {
case 0: return ConsoleColor.Black;
case 1: return ConsoleColor.DarkGray;
case 2: return ConsoleColor.Gray;
default: return ConsoleColor.White;
}
}
int hue = (int)Math.Round(color.GetHue()/60, MidpointRounding.AwayFromZero);
if (color.GetBrightness() < 0.4) {
// dark color
switch (hue) {
case 1: return ConsoleColor.DarkYellow;
case 2: return ConsoleColor.DarkGreen;
case 3: return ConsoleColor.DarkCyan;
case 4: return ConsoleColor.DarkBlue;
case 5: return ConsoleColor.DarkMagenta;
default: return ConsoleColor.DarkRed;
}
}
// bright color
switch (hue) {
case 1: return ConsoleColor.Yellow;
case 2: return ConsoleColor.Green;
case 3: return ConsoleColor.Cyan;
case 4: return ConsoleColor.Blue;
case 5: return ConsoleColor.Magenta;
default: return ConsoleColor.Red;
}
}
请注意,控制台的颜色名称与众所周知的颜色不匹配。所以如果你测试一个颜色映射方案,你必须记住(例如)在众所周知的颜色中,灰色是深灰色,浅灰色是灰色,绿色是深绿色,石灰是纯绿色,而橄榄色是黑暗的黄色。
您可以使用反射。
public static class ColorHelpers
{
public static bool TryGetConsoleColor(Color color, out ConsoleColor consoleColor)
{
foreach (PropertyInfo property in typeof (Color).GetProperties())
{
Color c = (Color) property.GetValue(null);
if (color == c)
{
int index = Array.IndexOf(Enum.GetNames(typeof (ConsoleColor)), property.Name);
if (index != -1)
{
consoleColor = (ConsoleColor) Enum.GetValues(typeof (ConsoleColor)).GetValue(index);
return true;
}
}
}
consoleColor = default (ConsoleColor);
return false;
}
}
用法:
private static void Main()
{
ConsoleColor c;
if (ColorHelpers.TryGetConsoleColor(Color.Red, out c))
{
Console.ForegroundColor = c;
}
}
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;
}
的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
可以大致映射一个24位彩色(或者32位颜色,通过忽略alpha通道)转换为具有亮度分量的基本3位颜色。在这种情况下,如果任何System.Drawing.Color的红色,绿色或蓝色字节大于128,则设置'亮度'位,如果等效源字节大于64,则设置红色,绿色和蓝色位
- 1. 将Consolecolor转换为彩色?
- 2. C#将4位颜色(= ConsoleColor)转换为RGB并返回
- 3. 将uint转换为颜色
- 4. 将CMYK PDF转换为专色(颜色)
- 5. php将irc颜色转换为html
- 6. 将整数转换为WPF的颜色
- 7. 将整数颜色值转换为RGB
- 8. 将颜色从colorWithRGBA转换为colorWithWhite
- 9. 将Pantone颜色转换为RGB?
- 10. 将矩阵转换为颜色网格
- 11. 如何将颜色值转换为RGB
- 12. 将XYZ颜色转换为RGB
- 13. XAML:将笔刷转换为颜色?
- 14. 将颜色名称转换为RGB
- 15. 将字符串转换为swt颜色
- 16. 将实验室颜色转换为RGB
- 17. 将css颜色转换为16位rgb
- 18. iOS将颜色转换为RGB
- 19. 将画笔转换为颜色
- 20. Android - 将ARGB颜色转换为RGB
- 21. 将RGB转换为CIELAB颜色空间
- 22. 将字符串转换为颜色int
- 23. 将颜色整数转换为文本?
- 24. 将8位颜色转换为RGB值
- 25. Matlab将RBG颜色转换为decimale值
- 26. 将NSString颜色名称转换为UIColor
- 27. Actionscript flex:将#个颜色转换为uint
- 28. 将字符串转换为颜色VB.NET
- 29. 如何将RGB转换为HTML颜色?
- 30. 将RGB颜色转换为OLE_Color
我建议看看http://stackoverflow.com/questions/28211009,而不是遵循这里提供的任何(所有错误)答案> _> – mafu 2015-01-29 09:47:58