我想要为游戏编写类似控制台的gui,我从一个真正的控制台开始。所以我有一个指定颜色的类。现在我想将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位颜色有这个位:shegb。当d为0时,颜色将变暗,如果它为1,则rgb值为255.我的问题是:我的程序中颜色1000(亮黑)和颜色0111(深白)是黑色和灰色。它们应该是黑色和浅灰色的。如何通过舍入转换颜色,而不仅仅是转换特定的颜色?
答案 0 :(得分: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();
答案 1 :(得分:2)
颜色在三维参数空间中定义,具有三个坐标轴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;
}
}
答案 2 :(得分: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;