将4位颜色(=ConsoleColor)转换为RGB并返回

本文关键字:转换 RGB 返回 ConsoleColor 4位 颜色 | 更新日期: 2023-09-27 18:04:50

我想为一款游戏编写一个类似主机的gui,我从一个真正的主机开始。我有一个指定颜色的类。现在我想将控制台颜色转换为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(暗白色)是黑色和灰色在我的程序。它们应该是深灰色和浅灰色。如何将四舍五入的颜色转换回来而不只是将特定的颜色转换回来?

将4位颜色(=ConsoleColor)转换为RGB并返回

颜色是用三个坐标轴R, G和b在三维参数空间中定义的。您可以这样计算两种颜色ab之间的距离:

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;
    }
}

一种更复杂的方法是使用Floyd-Steinberg抖动这样的算法,不仅可以逐像素降低颜色深度,还可以将转换误差分散到几个像素中,从而产生具有微妙颜色细微差别的错觉。

浅灰色是一种特殊的颜色,你只需要单独处理。

您可以使用颜色的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;