ColorQuantizer.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. namespace Terminal.Gui;
  2. /// <summary>
  3. /// Translates colors in an image into a Palette of up to 256 colors.
  4. /// </summary>
  5. public class ColorQuantizer
  6. {
  7. private Dictionary<Color, int> colorFrequency;
  8. public List<Color> Palette;
  9. private const int MaxColors = 256;
  10. public ColorQuantizer ()
  11. {
  12. colorFrequency = new Dictionary<Color, int> ();
  13. Palette = new List<Color> ();
  14. }
  15. public void BuildColorPalette (Color [,] pixels)
  16. {
  17. int width = pixels.GetLength (0);
  18. int height = pixels.GetLength (1);
  19. // Count the frequency of each color
  20. for (int x = 0; x < width; x++)
  21. {
  22. for (int y = 0; y < height; y++)
  23. {
  24. Color color = pixels [x, y];
  25. if (colorFrequency.ContainsKey (color))
  26. {
  27. colorFrequency [color]++;
  28. }
  29. else
  30. {
  31. colorFrequency [color] = 1;
  32. }
  33. }
  34. }
  35. // Create a sorted list of colors based on frequency
  36. var sortedColors = colorFrequency.OrderByDescending (kvp => kvp.Value).ToList ();
  37. // Build the Palette with the most frequent colors up to MaxColors
  38. Palette = sortedColors.Take (MaxColors).Select (kvp => kvp.Key).ToList ();
  39. }
  40. public int GetNearestColor (Color toTranslate)
  41. {
  42. // Simple nearest color matching based on Euclidean distance in RGB space
  43. double minDistance = double.MaxValue;
  44. int nearestIndex = 0;
  45. for (var index = 0; index < Palette.Count; index++)
  46. {
  47. Color color = Palette [index];
  48. double distance = ColorDistance (color, toTranslate);
  49. if (distance < minDistance)
  50. {
  51. minDistance = distance;
  52. nearestIndex = index;
  53. }
  54. }
  55. return nearestIndex;
  56. }
  57. private double ColorDistance (Color c1, Color c2)
  58. {
  59. // Euclidean distance in RGB space
  60. int rDiff = c1.R - c2.R;
  61. int gDiff = c1.G - c2.G;
  62. int bDiff = c1.B - c2.B;
  63. return Math.Sqrt (rDiff * rDiff + gDiff * gDiff + bDiff * bDiff);
  64. }
  65. }