Qual è il modo migliore per convertire uno System.Drawing.Color
in uno System.ConsoleColor
simile?Conversione del colore in ConsoleColor?
risposta
Sfortunatamente, anche se la console di Windows può supportare i colori RGB, la classe Console espone solo l'enumerazione ConsoleColor che limita notevolmente i colori possibili che è possibile utilizzare. Se vuoi che una struttura Color venga mappata sul ConsoleColor "più vicino", sarà difficile.
Ma se si desidera che il nome di colore per abbinare un corrispondente ConsoleColor si può fare una mappa come ad esempio:
var map = new Dictionary<Color, ConsoleColor>();
map[Color.Red] = ConsoleColor.Red;
map[Color.Blue] = ConsoleColor.Blue;
etc...
O se le prestazioni non è così importante, si può arrotondare viaggio attraverso String. (Funziona solo per i colori con nome )
var color = Enum.Parse(typeof(ConsoleColor), color.Name);
EDIT: Ecco un link ad un question about finding color "closeness".
È possibile senza la classe Console? –
Non sembra così. L'API Win32 SetConsoleTextAttribute definisce solo 4 flag x 1 bit per R, G, B, oltre a un bit di intensità. Ciò supporterà solo i 16 colori supportati dall'enum ConsoleColor. – Josh
Ma hai detto che la console di Windows supporta qualsiasi colore RGB ... –
Su Vista e successivamente vedere la funzione API SetConsoleScreenBufferInfoEx.
Per un esempio di utilizzo, fare riferimento a my answer in un'altra domanda StackOverflow molto simile. (Grazie Hans Passant per la risposta originale).
Qui ci sono i valori esadecimali dei colori della console, come convertito dalla .NET 4.5. Prima il programma:
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);
}
}
Ed ecco l'output. Come puoi vedere, c'è un problema con la segnalazione di DarkYellow
. I 32 bit completi di quello vengono visualizzati come zero. Tutti gli altri hanno 0xFF per il canale alfa.
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: ho avuto un po 'di più trasportare in questo momento, quindi ecco un convertitore da RGB
al valore più vicino ConsoleColor
. Si noti che la dipendenza da System.Windows.Media
è solo per il cablaggio dimostrativo; la funzione stessa si riferisce solo a 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));
}
}
}
L'uscita (parziale) ...
Il codice esadecimale DarkYellow sopra (l'inizio del post) è errato. Dice # 000000, ma dovrebbe essere # d7c32a (come indicato qui => http://rgb.to/color/6990/dark-yellow) – SuperJMN
@SuperJMN Si prega di notare il mio commento nel post originale: "Come puoi vedere , c'è un problema con la segnalazione di DarkYellow. " –
Oh, OK! Non ho letto che è un output del programma. Ho usato quei valori esadecimali per la mia versione del tuo algoritmo e ho realizzato il problema quando ho aggiunto i valori a un dizionario :) Scusa! – SuperJMN
Un approccio semplice ed efficace può essere attuato utilizzando i GetHue
, GetBrightness
e GetSaturation
metodi della classe Color
.
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;
}
}
Si noti che i nomi dei colori della console non corrispondono ai colori noti. Quindi, se si prova uno schema di mappatura dei colori, devi tenere a mente che (per esempio) nei colori ben noti, Gray è grigio scuro, grigio chiaro è grigio, il verde è verde scuro, calce è verde puro, e Olive è buio giallo.
È possibile utilizzare la riflessione.
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;
}
}
Usage:
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;
}
Il ConsoleColors enumerazione sembra utilizzare la tavolozza ordinamento stile EGA, che è:
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
È possibile circa mappare un colore a 24 bit (o colore a 32 bit, ignorando il canale alfa) a ciò che è essenzialmente un colore a 3 bit con un componente di luminosità. In questo caso, il bit "luminosità" viene impostato se uno qualsiasi dei byte rosso, verde o blu di System.Drawing.Color è maggiore di 128 e i bit rosso, verde e blu vengono impostati se i byte di origine equivalenti sono superiori a 64
- 1. Conversione da system.windows.media.brush a codice colore esadecimale
- 2. Conversione tra spazi colore RGB e RYB
- 3. C# Conversione Delphi TColor al colore (Hex)
- 4. Conversione da stringa a colore Java/Android
- 5. Conversione del nome del mese in intero
- 6. Conversione da Int a colore in C# per Silverrit WriteableBitmap
- 7. ImageMagick cambia colore durante la conversione di PDF in immagini
- 8. Modifica del colore del testo in Java
- 9. Modifica del colore del cubo in three.js
- 10. Conversione non riuscita durante la conversione del valore varchar in
- 11. Conversione del plug-in Eclipse in Intellij
- 12. conversione del numero in stringa in lisp
- 13. Conversione del dizionario in JSON in python
- 14. Conversione del tempo in DateTempo in C#
- 15. Rendi il colore del link uguale al colore del testo senza conoscere il colore del testo?
- 16. Cambia colore del testo in base al colore di sfondo
- 17. Punti colore in base al colore del contorno
- 18. Cambia colore del testo senza memoria colore in C64/Assembly
- 19. Animazione del colore del testo
- 20. Modifica del colore di sfondo e del colore del testo in una casella di testo
- 21. Colore del colore del collegamento per TTTAttribuito Etichetta
- 22. Implementazione del colore personalizzato
- 23. Conversione del byte del certificato [] in X509Certificato in Java
- 24. C++ Win32 Console Colore
- 25. Conversione del fuso orario in php
- 26. conversione del codice MATLAB in Fortran
- 27. Conversione implicita del tipo in C
- 28. Conversione del byte C# in BitArray
- 29. Conversione del vecchio makefile in CMake
- 30. Conversione del carattere unicode in formato stringa
Suggerisco di dare un'occhiata a http://stackoverflow.com/questions/28211009 invece di seguire una qualsiasi delle risposte (tutte sbagliate) presentate qui> _> – mafu