123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- namespace Terminal.Gui;
- /// <summary>
- /// Translates colors in an image into a Palette of up to 256 colors.
- /// </summary>
- public class ColorQuantizer
- {
- private Dictionary<Color, int> colorFrequency;
- public List<Color> Palette;
- private const int MaxColors = 256;
- public ColorQuantizer ()
- {
- colorFrequency = new Dictionary<Color, int> ();
- Palette = new List<Color> ();
- }
- 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);
- }
- }
|