将 RGB 值转换为 ConsoleColor (C#)

问题描述 投票:0回答:1

所以我希望构建一个 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

c# colors console console-application
1个回答
0
投票

我想通了! 对于那些想知道的人,这就是我所做的。

// 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
© www.soinside.com 2019 - 2024. All rights reserved.