1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.palette;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.apache.commons.imaging.ImagingException;
23
24 final class ColorGroup {
25
26
27 ColorGroupCut cut;
28
29 int paletteIndex = -1;
30
31 private final List<ColorCount> colorCounts;
32 final boolean ignoreAlpha;
33 int minRed = Integer.MAX_VALUE;
34 int maxRed = Integer.MIN_VALUE;
35 int minGreen = Integer.MAX_VALUE;
36 int maxGreen = Integer.MIN_VALUE;
37 int minBlue = Integer.MAX_VALUE;
38 int maxBlue = Integer.MIN_VALUE;
39 int minAlpha = Integer.MAX_VALUE;
40 int maxAlpha = Integer.MIN_VALUE;
41
42 final int alphaDiff;
43 final int redDiff;
44 final int greenDiff;
45 final int blueDiff;
46
47 final int maxDiff;
48 final int diffTotal;
49 final int totalPoints;
50
51 ColorGroup(final List<ColorCount> colorCounts, final boolean ignoreAlpha) throws ImagingException {
52 this.colorCounts = colorCounts;
53 this.ignoreAlpha = ignoreAlpha;
54
55 if (colorCounts.isEmpty()) {
56 throw new ImagingException("Empty colorCounts");
57 }
58
59 int total = 0;
60 for (final ColorCount color : colorCounts) {
61 total += color.count;
62
63 minAlpha = Math.min(minAlpha, color.alpha);
64 maxAlpha = Math.max(maxAlpha, color.alpha);
65 minRed = Math.min(minRed, color.red);
66 maxRed = Math.max(maxRed, color.red);
67 minGreen = Math.min(minGreen, color.green);
68 maxGreen = Math.max(maxGreen, color.green);
69 minBlue = Math.min(minBlue, color.blue);
70 maxBlue = Math.max(maxBlue, color.blue);
71 }
72 this.totalPoints = total;
73
74 alphaDiff = maxAlpha - minAlpha;
75 redDiff = maxRed - minRed;
76 greenDiff = maxGreen - minGreen;
77 blueDiff = maxBlue - minBlue;
78 maxDiff = Math.max(ignoreAlpha ? redDiff : Math.max(alphaDiff, redDiff), Math.max(greenDiff, blueDiff));
79 diffTotal = (ignoreAlpha ? 0 : alphaDiff) + redDiff + greenDiff + blueDiff;
80 }
81
82 boolean contains(final int argb) {
83 final int alpha = 0xff & argb >> 24;
84 final int red = 0xff & argb >> 16;
85 final int green = 0xff & argb >> 8;
86 final int blue = 0xff & argb >> 0;
87
88 if (!ignoreAlpha && (alpha < minAlpha || alpha > maxAlpha)) {
89 return false;
90 }
91 if (red < minRed || red > maxRed) {
92 return false;
93 }
94 if (green < minGreen || green > maxGreen) {
95 return false;
96 }
97 if (blue < minBlue || blue > maxBlue) {
98 return false;
99 }
100 return true;
101 }
102
103
104
105
106
107
108 List<ColorCount> getColorCounts() {
109 return new ArrayList<>(colorCounts);
110 }
111
112 int getMedianValue() {
113 long countTotal = 0;
114 long alphaTotal = 0;
115 long redTotal = 0;
116 long greenTotal = 0;
117 long blueTotal = 0;
118
119 for (final ColorCount color : colorCounts) {
120 countTotal += color.count;
121 alphaTotal += color.count * color.alpha;
122 redTotal += color.count * color.red;
123 greenTotal += color.count * color.green;
124 blueTotal += color.count * color.blue;
125 }
126
127 final int alpha = ignoreAlpha ? 0xff : (int) Math.round((double) alphaTotal / countTotal);
128 final int red = (int) Math.round((double) redTotal / countTotal);
129 final int green = (int) Math.round((double) greenTotal / countTotal);
130 final int blue = (int) Math.round((double) blueTotal / countTotal);
131
132 return alpha << 24 | red << 16 | green << 8 | blue;
133 }
134
135 @Override
136 public String toString() {
137 return "{ColorGroup. minRed: " + Integer.toHexString(minRed) + ", maxRed: " + Integer.toHexString(maxRed) + ", minGreen: "
138 + Integer.toHexString(minGreen) + ", maxGreen: " + Integer.toHexString(maxGreen) + ", minBlue: " + Integer.toHexString(minBlue) + ", maxBlue: "
139 + Integer.toHexString(maxBlue) + ", minAlpha: " + Integer.toHexString(minAlpha) + ", maxAlpha: " + Integer.toHexString(maxAlpha) + ", maxDiff: "
140 + Integer.toHexString(maxDiff) + ", diffTotal: " + diffTotal + "}";
141 }
142
143 }