private Dictionary <int, ColorData> GetMedianCutTable(List <ColorDataBox> boxes) { Dictionary <int, ColorData> medianCutTable = new Dictionary <int, ColorData>(); for (int i = 0; i < boxes.Count; i++) { ColorDataBox box = boxes[i]; int centerR = box.MinR + box.LengthR / 2; int centerG = box.MinG + box.LengthG / 2; int centerB = box.MinB + box.LengthB / 2; medianCutTable.Add(i, new ColorData(centerR, centerG, centerB)); } return(medianCutTable); }
private List <ColorData>[] CountSort(ColorDataBox box, ColorChannel cc) { List <ColorData>[] colorTable = new List <ColorData> [256]; for (int i = 0; i < 256; i++) { colorTable[i] = new List <ColorData>(); } for (int i = 0; i < box.ColorData.Length; i++) { ColorData data = box.ColorData[i]; colorTable[data.GetValue(cc)].Add(data); } return(colorTable); }
private void GetImage(ImageData data, int bits) { int bitCount = (int)Math.Pow(2, bits); List <ColorDataBox> boxes = new List <ColorDataBox>(); ColorData[] colors = new ColorData[data.RGBValues.Length / 3]; for (int i = 0; i < data.RGBValues.Length; i += 3) { colors[i / 3] = new ColorData(data.RGBValues[i + 2], data.RGBValues[i + 1], data.RGBValues[i]); } ColorDataBox totalBox = new ColorDataBox(colors); boxes.Add(totalBox); for (int i = 0; i < bitCount - 1; i++) { int index = GetLargestBox(boxes); ColorDataBox box = boxes[index]; boxes.RemoveAt(index); ColorChannel channel = ColorChannel.Red; if (box.LengthR >= box.LengthG && box.LengthR >= box.LengthB) { channel = ColorChannel.Red; } else { if (box.LengthG >= box.LengthB) { channel = ColorChannel.Green; } else { channel = ColorChannel.Blue; } } List <ColorData>[] colorTable = CountSort(box, channel); List <ColorData> box1 = new List <ColorData>(); List <ColorData> box2 = new List <ColorData>(); int sum = 0; int half = box.ColorData.Length / 2; foreach (List <ColorData> colorData in colorTable) { if (sum < half) { if (sum + colorData.Count > half) { int diff = sum + colorData.Count - half; box1.AddRange(colorData.GetRange(0, diff)); box2.AddRange(colorData.GetRange(diff, colorData.Count - diff)); } else { box1.AddRange(colorData); } } else { box2.AddRange(colorData); } sum += colorData.Count; } boxes.Add(new ColorDataBox(box1.ToArray())); boxes.Add(new ColorDataBox(box2.ToArray())); } Dictionary <int, ColorData> medianCutTable = GetMedianCutTable(boxes); int[,,] indexTable = new int[256, 256, 256]; for (int r = 0; r < 256; r++) { for (int g = 0; g < 256; g++) { for (int b = 0; b < 256; b++) { indexTable[r, g, b] = -1; } } } for (int i = 0; i < data.RGBValues.Length; i += 3) { ColorData colorData = colors[i / 3]; int index = indexTable[colorData.Red, colorData.Green, colorData.Blue]; if (index == -1) { index = GetContainingBox(colorData, boxes); indexTable[colorData.Red, colorData.Green, colorData.Blue] = index; } ColorData newColor = medianCutTable[index]; data.RGBValues[i + 2] = (byte)newColor.Red; data.RGBValues[i + 1] = (byte)newColor.Green; data.RGBValues[i] = (byte)newColor.Blue; } }