namespace Terminal.Gui; /// /// Translates colors in an image into a Palette of up to 256 colors. /// public class ColorQuantizer { private Dictionary colorFrequency; public List Palette; private const int MaxColors = 256; public ColorQuantizer () { colorFrequency = new Dictionary (); Palette = new List (); } public void BuildColorPalette (Color [,] pixels) { int width = pixels.GetLength (0); int height = pixels.GetLength (1); // Count the frequency of each color for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Color color = pixels [x, y]; if (colorFrequency.ContainsKey (color)) { colorFrequency [color]++; } else { colorFrequency [color] = 1; } } } // Create a sorted list of colors based on frequency var sortedColors = colorFrequency.OrderByDescending (kvp => kvp.Value).ToList (); // Build the Palette with the most frequent colors up to MaxColors Palette = sortedColors.Take (MaxColors).Select (kvp => kvp.Key).ToList (); } public int GetNearestColor (Color toTranslate) { // Simple nearest color matching based on Euclidean distance in RGB space double minDistance = double.MaxValue; int nearestIndex = 0; for (var index = 0; index < Palette.Count; index++) { Color color = Palette [index]; double distance = ColorDistance (color, toTranslate); if (distance < minDistance) { minDistance = distance; nearestIndex = index; } } return nearestIndex; } private double ColorDistance (Color c1, Color c2) { // Euclidean distance in RGB space int rDiff = c1.R - c2.R; int gDiff = c1.G - c2.G; int bDiff = c1.B - c2.B; return Math.Sqrt (rDiff * rDiff + gDiff * gDiff + bDiff * bDiff); } }