//TODO : Needs some work, like R,G,B weighting as opposed to a stright-up-the-middle, first stab public static Dictionary <string, Color> PaletteReducer(Dictionary <string, Color> original, int paletteCount) { if (original.Keys.Count < paletteCount) { return(original); } Dictionary <string, Color> reducedPalette = new Dictionary <string, Color>(); // Divide the RBG space into paletteCount as a line through the middle of the space and find nearest neighbour to the that line. // When the nearest color is found, it must be removed from the list of eligible colors. int units = 255 / paletteCount; for (int i = 0; i < paletteCount; i++) { // Straight up the middle of the 3D color space Color testColor = Color.FromArgb(255, units * i, units * 1, units * i); ColorTuple t = testColor.ClosestColor(original); reducedPalette.Add(t.Name, t.ColorValue); original.Remove(t.Name); } return(reducedPalette); }
public static ColorTuple ClosestColor(this Color original, Dictionary <string, Color> palette) { // Middle of the color range yields significantly better results as a default. ColorTuple closest = new ColorTuple("Blank", Color.FromArgb(255, 128, 128, 128)); foreach (string key in palette.Keys) { if (palette[key].ColorDiff(original) <= closest.ColorValue.ColorDiff(original)) { closest.Name = key; closest.ColorValue = palette[key]; } } return(closest); }