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;
Другие вопросы по тегам