C# Конвертировать 4-битный цвет (=ConsoleColor) в RGB и обратно
Я хочу написать консольный интерфейс для игры, и я начну с настоящей консоли. Итак, у меня есть класс, который определяет цвета. Теперь я хочу преобразовать consolecolor в rgb (24 бит) и наоборот. Я попробовал это:
int d = (((int)col & 8) != 0) ? 255 : 128;
r = (((int)col & 4) != 0) ? d : 0;
g = (((int)col & 2) != 0) ? d : 0;
b = (((int)col & 1) != 0) ? d : 0;
4 Битовые цвета имеют этот бит-шем: drgb. Когда d равно 0, цвет будет темным, если он равен 1, значения rgb будут 255. Моя проблема: цвета 1000 (ярко-черный) и цвет 0111 (темно-белый) являются черными и серыми в моей программе. они должны быть темно-серыми и светло-серыми. И как конвертировать цвета обратно с округлением, а не просто конвертировать обратно определенные цвета?
3 ответа
Цвета определены в трехмерном пространстве параметров с тремя осями координат R, G и B. Вы можете рассчитать расстояние между двумя цветами a
а также b
как это:
double dist = Math.Sqrt(Sqr(a.R - b.R) + Sqr(a.G - b.G) + Sqr(a.B - b.B));
Эта формула использует этот метод
private static int Sqr(int x)
{
return x * x;
}
Лучший подходящий цвет - тот, у которого наименьшее расстояние. Вы также можете использовать квадрат расстояния для сравнения расстояний (для эффективности):
int sqrDist = Sqr(a.R - b.R) + Sqr(a.G - b.G) + Sqr(a.B - b.B);
Теперь определим массив с 16 консольными цветами:
Color[] consoleColors = new[] {
Colors.Black,
Colors.Red,
...
};
и получить лучший матч с
Color bestMatch;
int bestSqrDist = Int32.MaxValue;
foreach (Color consoleColor in consoleColors) {
int sqrDist = Sqr(theColor.R - consoleColor.R) +
Sqr(theColor.G - consoleColor.G) +
Sqr(theColor.B - consoleColor.B);
if (sqrDist < bestSqrDist) {
bestMatch = consoleColor;
bestSqrDist = sqrDist;
}
}
Светло-серый цвет - это особый случай, вам нужно обращаться с ним отдельно.
Вы можете установить массивы со значениями RGB для цветов и использовать их для преобразования, они будут полезны, когда вы собираетесь преобразовать цвета обратно.
Преобразование 24-битных цветов в палитру из 16 цветов может быть выполнено различными способами. Один из способов - вычислить разницу между цветом RGB и цветами палитры и выбрать цвет с наименьшей разницей:
Пример:
byte[] r = { 0, 0, 0, 0, 128, 128, 128, 128, 192, 0, 0, 0, 255, 255, 255, 255 };
byte[] g = { 0, 0, 128, 128, 0, 0, 128, 128, 192, 0, 255, 255, 0, 0, 255, 255 };
byte[] b = { 0, 128, 0, 128, 0, 128, 0, 128, 192, 255, 0, 255, 0, 255, 0, 255 };
Color c = Color.Khaki;
int index = Enumerable.Range(0, 16)
.OrderBy(i => Math.Abs(c.R - r[i]) + Math.Abs(c.G - g[i]) + Math.Abs(c.B - b[i]))
.First();
Я не уверен, правильно ли я вас понял, но попробуйте это:
int d = (((int)col & 8) != 0) ? 64 : 0;
r = (((int)col & 4) != 0) ? d + 191 : d;
g = (((int)col & 2) != 0) ? d + 191 : d;
b = (((int)col & 1) != 0) ? d + 191 : d;