static int[] GetHistogram(Color[] pixels) { var size = 1 << (3 * SIGBITS); var histogram = new int[size]; int index; foreach (var pixel in pixels) { index = MMCQ.GetColorIndex( pixel.R >> RSHIFT, pixel.G >> RSHIFT, pixel.B >> RSHIFT ); histogram[index] = histogram[index] + 1; } return(histogram); }
public int GetCount(bool forced = false) { if (!_count_set || forced) { int numpix = 0, index; for (int r = R1; r <= R2; r++) { for (int g = G1; g <= G2; g++) { for (int b = B1; b <= B2; b++) { index = MMCQ.GetColorIndex(r, g, b); numpix += _histogram[index]; } } } _count_set = true; _count = numpix; } return(_count); }
public Color GetAverage(bool forced = false) { if (!_average_set || forced) { int mult = 1 << (8 - MMCQ.SIGBITS), total = 0, rsum = 0, gsum = 0, bsum = 0, index, hval; for (int r = R1; r <= R2; r++) { for (int g = G1; g <= G2; g++) { for (int b = B1; b <= B2; b++) { index = MMCQ.GetColorIndex(r, g, b); hval = _histogram[index]; total += hval; rsum += (int)(hval * (r + .5) * mult); gsum += (int)(hval * (g + .5) * mult); bsum += (int)(hval * (b + .5) * mult); } } } if (total > 0) { _average = Color.FromArgb(~~(rsum / total), ~~(gsum / total), ~~(bsum / total)); } else { _average = Color.FromArgb( ~~(mult * (R1 + R2 + 1) / 2) - 1, ~~(mult * (G1 + G2 + 1) / 2) - 1, ~~(mult * (B1 + B2 + 1) / 2) - 1 ); } } _average_set = true; return(_average); }
static ColorBox[] MedianCutApply(int[] histogram, ColorBox box) { if (box.GetCount() == 0) { return(null); } if (box.GetCount() == 1) { return new ColorBox[2] { box.Copy(), null } } ; int rw = box.R2 - box.R1 + 1, gw = box.G2 - box.G1 + 1, bw = box.B2 - box.B1 + 1, maxw = Math.Max(rw, Math.Max(gw, bw)), total = 0, sum, index; var partialSum = new int[0]; if (maxw == rw) { partialSum = new int[box.R2 + 1]; for (int r = box.R1; r <= box.R2; r++) { sum = 0; for (int g = box.G1; g <= box.G2; g++) { for (int b = box.B1; b <= box.B2; b++) { index = MMCQ.GetColorIndex(r, g, b); sum += histogram[index]; } } total += sum; partialSum[r] = total; } } else if (maxw == gw) { partialSum = new int[box.G2 + 1]; for (int g = box.G1; g <= box.G2; g++) { sum = 0; for (int r = box.R1; r <= box.R2; r++) { for (int b = box.B1; b <= box.B2; b++) { index = MMCQ.GetColorIndex(r, g, b); sum += histogram[index]; } } total += sum; partialSum[g] = total; } } else if (maxw == bw) { partialSum = new int[box.B2 + 1]; for (int b = box.B1; b <= box.B2; b++) { sum = 0; for (int r = box.R1; r <= box.R2; r++) { for (int g = box.G1; g <= box.G2; g++) { index = MMCQ.GetColorIndex(r, g, b); sum += histogram[index]; } } total += sum; partialSum[b] = total; } } var lookAheadSum = new int[partialSum.Length]; for (int i = 0; i < partialSum.Length; i++) { lookAheadSum[i] = total - partialSum[i]; } if (maxw == rw) { return(DoCut(box, partialSum, lookAheadSum, total, 'r')); } if (maxw == gw) { return(DoCut(box, partialSum, lookAheadSum, total, 'g')); } if (maxw == bw) { return(DoCut(box, partialSum, lookAheadSum, total, 'b')); } return(null); }