0

我想为游戏编写一个类似控制台的 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

3 回答 3

2

浅灰色是特殊情况,您只需要单独处理即可。

您可以使用颜色的 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();
于 2014-05-24T15:30:27.460 回答
2

颜色是在具有三个坐标轴 R、G 和 B 的 3 维参数空间中定义的。您可以计算两种颜色之间的距离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;
    }
}
于 2014-05-24T15:36:26.523 回答
1

我不确定我是否理解正确,但试试这个:

    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;
于 2014-05-24T15:24:05.363 回答