所以我希望构建一个 ASCII 渲染器,它获取图像并将每个像素转换为字符。但是,我认为如果我还可以获得颜色值,而不仅仅是白色字符,那就太酷了。然而我遇到了一个问题:我使用的图像格式(PPM,为了方便起见)使用 RGB 值,而 C# 控制台只有 16 种颜色,所以我需要估计颜色。然而问题来了,我尝试过的方法都不起作用。
这是我尝试过的片段:
static ConsoleColor FindClosestConsoleColor(int r, int g, int b)
{
ConsoleColor closest = ConsoleColor.Black;
double closestDist = double.MaxValue;
foreach (ConsoleColor consoleColor in Enum.GetValues(typeof(ConsoleColor)))
{
if (consoleColor == ConsoleColor.Black || consoleColor == ConsoleColor.DarkBlue || consoleColor == ConsoleColor.DarkCyan ||
consoleColor == ConsoleColor.DarkGreen || consoleColor == ConsoleColor.DarkMagenta || consoleColor == ConsoleColor.DarkRed ||
consoleColor == ConsoleColor.DarkYellow || consoleColor == ConsoleColor.Gray || consoleColor == ConsoleColor.DarkGray ||
consoleColor == ConsoleColor.Blue || consoleColor == ConsoleColor.Cyan || consoleColor == ConsoleColor.Green ||
consoleColor == ConsoleColor.Magenta || consoleColor == ConsoleColor.Red || consoleColor == ConsoleColor.Yellow ||
consoleColor == ConsoleColor.White)
{
int consoleColorValue = (int)consoleColor;
int consoleRed = (consoleColorValue & 0xFF0000) >> 16;
int consoleGreen = (consoleColorValue & 0x00FF00) >> 8;
int consoleBlue = consoleColorValue & 0x0000FF;
// Calculate the Euclidean distance between the two colors
double distance = Math.Sqrt(Math.Pow(consoleRed - r, 2) + Math.Pow(consoleGreen - g, 2) + Math.Pow(consoleBlue - b, 2));
// Check if this ConsoleColor is closer to the given RGB values
if (distance < closestDist)
{
closestDist = distance;
closest = consoleColor;
}
}
}
return closest;
}
然而,这个片段只返回黑色,即使我直接喂它红色。 (255, 0, 0)
我也尝试阅读这篇 StackOverflow 文章,但那是针对
System.Drawing.Color
命名空间的。我希望将原始 RGB 值转换为 ConsoleColor。
如有任何帮助,我们将不胜感激! 谢谢,游戏12
我想通了! 对于那些想知道的人,这就是我所做的。
// First, I defined a list of the ConsoleColor's RGB values as an array of int tuples
private static readonly (int, int, int)[] colorValuesInt = new (int, int, int)[] {
(0, 0, 255), (0, 255, 255), (0, 0, 128), (0, 139, 139), (169, 169, 169), (0, 100, 0), (139, 0, 139), (139, 0, 0), (139, 139, 0), (128, 128, 128), (0, 128, 0), (255, 0, 255), (255, 0, 0), (255, 255, 255), (255, 255, 0)
};
// Then used this function
public static Color RGBToConsoleColor(int r, int g, int b) {
// Make a lamda square function
Func<int, int> square = (int x) => x * x;
Color[] consoleColors = new[] {
Color.Blue, Color.Cyan, Color.DarkBlue, Color.DarkCyan, Color.DarkGray, Color.DarkGreen, Color.DarkMagenta, Color.DarkRed, Color.DarkYellow, Color.Gray, Color.Green, Color.Magenta, Color.Red, Color.White, Color.Yellow
};
Color best = Color.Black;
int bestSquareDistance = Int32.MaxValue;
for (int i = 0; i < consoleColors.Length; i++) {
Color c = consoleColors[i];
(int, int, int) colorValues = colorValuesInt[i];
int squareDistance = square(r - colorValues.Item1) + square(g - colorValues.Item2) + square(b - colorValues.Item3);
if (squareDistance < bestSquareDistance) {
best = c;
bestSquareDistance = squareDistance;
}
}
return best;
}
Thanks so much to @Serg, they provided articles that helped me figure it out :D