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 static org.junit.jupiter.api.Assertions.assertEquals;
20
21 import java.awt.image.BufferedImage;
22
23 import org.apache.commons.imaging.AbstractImagingTest;
24 import org.apache.commons.imaging.ImagingException;
25 import org.junit.jupiter.api.Test;
26
27 public class PaletteQuantizationTest extends AbstractImagingTest {
28
29 private void checkPaletteDetails(final BufferedImage image, final int limit, final int expectedSize) throws ImagingException {
30 final PaletteFactory paletteFactory = new PaletteFactory();
31 Palette palette;
32
33 palette = paletteFactory.makeExactRgbPaletteSimple(image, limit);
34
35 boolean exact = false;
36 if (palette != null) {
37 assertEquals(expectedSize, palette.length());
38
39 exact = true;
40 }
41 if (exact) {
42
43 }
44
45 palette = paletteFactory.makeQuantizedRgbaPalette(image, false, limit);
46 assertEquals(expectedSize, palette.length());
47 checkUniqueColors(image, palette);
48 if (exact) {
49 checkPixelsAreIdentical(image, palette);
50 }
51
52 palette = paletteFactory.makeQuantizedRgbPalette(image, limit);
53 assertEquals(expectedSize, palette.length());
54
55 if (exact) {
56
57 }
58
59 final MedianCutQuantizer medianCutQuantizer = new MedianCutQuantizer(true);
60 palette = medianCutQuantizer.process(image, limit, new MostPopulatedBoxesMedianCut());
61 assertEquals(expectedSize, palette.length());
62 checkUniqueColors(image, palette);
63 if (exact) {
64 checkPixelsAreIdentical(image, palette);
65 }
66 }
67
68 private void checkPixelsAreIdentical(final BufferedImage src, final Palette palette) throws ImagingException {
69 final BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
70 dst.getGraphics().drawImage(src, 0, 0, src.getWidth(), src.getHeight(), null);
71 Dithering.applyFloydSteinbergDithering(dst, palette);
72 for (int y = 0; y < src.getHeight(); y++) {
73 for (int x = 0; x < src.getWidth(); x++) {
74 assertEquals(src.getRGB(x, y), dst.getRGB(x, y));
75 }
76 }
77 }
78
79 private void checkUniqueColors(final BufferedImage src, final Palette palette) throws ImagingException {
80 final BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
81 dst.getGraphics().drawImage(src, 0, 0, src.getWidth(), src.getHeight(), null);
82 Dithering.applyFloydSteinbergDithering(dst, palette);
83 final Palette ditheredPalette = new PaletteFactory().makeExactRgbPaletteSimple(dst, palette.length() * 2);
84 assertEquals(palette.length(), ditheredPalette.length());
85 }
86
87 @Test
88 public void testPaletteQuantization() throws ImagingException {
89 final BufferedImage whiteImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
90 for (int y = 0; y < whiteImage.getHeight(); y++) {
91 for (int x = 0; x < whiteImage.getWidth(); x++) {
92 whiteImage.setRGB(x, y, 0xFFFFFF);
93 }
94 }
95 checkPaletteDetails(whiteImage, 10, 1);
96
97 final BufferedImage whiteAndBlackImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
98 for (int y = 0; y < whiteImage.getHeight(); y++) {
99 for (int x = 0; x < 5; x++) {
100 whiteAndBlackImage.setRGB(x, y, 0xFFFFFF);
101 }
102 for (int x = 5; x < 10; x++) {
103 whiteAndBlackImage.setRGB(x, y, 0x000000);
104 }
105 }
106 checkPaletteDetails(whiteAndBlackImage, 10, 2);
107
108 final BufferedImage rainbowImage = new BufferedImage(9, 10, BufferedImage.TYPE_INT_RGB);
109 for (int y = 0; y < whiteImage.getHeight(); y++) {
110 for (int x = 0; x < 3; x++) {
111 rainbowImage.setRGB(x, y, 0xFF0000);
112 }
113 for (int x = 3; x < 6; x++) {
114 rainbowImage.setRGB(x, y, 0x00FF00);
115 }
116 for (int x = 6; x < 9; x++) {
117 rainbowImage.setRGB(x, y, 0x0000FF);
118 }
119 }
120 checkPaletteDetails(rainbowImage, 10, 3);
121 checkPaletteDetails(rainbowImage, 2, 2);
122 }
123 }