private static (List <System.Drawing.Color> colors, Dictionary <System.Drawing.Color, int> lookup) MedianCut(List <System.Drawing.Color> allColors, int stages) { MedianCutNode node = MedianCutInternal(allColors, stages); List <List <Color> > bucketedColors = new List <List <Color> >(); node.GetColors(bucketedColors); List <System.Drawing.Color> colors = new List <System.Drawing.Color>(); foreach (List <Color> cs in bucketedColors) { colors.Add(cs[0]); // TODO: use average instead } Dictionary <System.Drawing.Color, int> colorLookupTable = new Dictionary <System.Drawing.Color, int>(); for (int ci = 0; ci < bucketedColors.Count; ++ci) { foreach (Color c in bucketedColors[ci]) { colorLookupTable.Add(c, ci); } } return(colors, colorLookupTable); }
private static MedianCutNode MedianCutInternal(List <System.Drawing.Color> colors, int stages) { if (colors.Count == 0) { return(new MedianCutNode()); } int minr = colors.Min(x => x.R); int maxr = colors.Max(x => x.R); int ming = colors.Min(x => x.G); int maxg = colors.Max(x => x.G); int minb = colors.Min(x => x.B); int maxb = colors.Max(x => x.B); int mina = colors.Min(x => x.A); int maxa = colors.Max(x => x.A); int diffr = maxr - minr; int diffg = maxg - ming; int diffb = maxb - minb; int diffa = maxa - mina; int biggestDiffIdx = 3; int biggestDiff = diffa; int biggestDiffMin = mina; int biggestDiffMax = maxa; if (biggestDiff < diffg) { biggestDiff = diffg; biggestDiffIdx = 1; biggestDiffMin = ming; biggestDiffMax = maxg; } if (biggestDiff < diffr) { biggestDiff = diffr; biggestDiffIdx = 0; biggestDiffMin = minr; biggestDiffMax = maxr; } if (biggestDiff < diffb) { biggestDiff = diffb; biggestDiffIdx = 2; biggestDiffMin = minb; biggestDiffMax = maxb; } int cutoff = (biggestDiffMin + biggestDiffMax + 1) / 2; List <Color> left = new List <Color>(); List <Color> right = new List <Color>(); foreach (Color c in colors) { if (c.GetColorComponent(biggestDiffIdx) < cutoff) { left.Add(c); } else { right.Add(c); } } MedianCutNode node = new MedianCutNode(); if (stages <= 1) { node.LeftColors = left; node.RightColors = right; } else { node.LeftChild = MedianCutInternal(left, stages - 1); node.RightChild = MedianCutInternal(right, stages - 1); } return(node); }