Skip to content

Commit 779a8af

Browse files
authored
added important PImage unit tests (#1049)
1 parent d8767d9 commit 779a8af

File tree

1 file changed

+317
-0
lines changed

1 file changed

+317
-0
lines changed
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
package processing.core;
2+
3+
import static org.junit.Assert.*;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
import java.io.File;
7+
import java.io.IOException;
8+
import java.util.Arrays;
9+
10+
public class PImageTest {
11+
12+
private PImage img;
13+
private PApplet applet;
14+
15+
@Before
16+
public void setUp() {
17+
applet = new PApplet();
18+
img = new PImage(10, 10, PConstants.ARGB);
19+
for (int i = 0; i < img.pixels.length; i++) {
20+
img.pixels[i] = 0xFF000000 | (i % 255) << 16 | ((i * 3) % 255) << 8 | ((i * 7) % 255);
21+
}
22+
img.updatePixels();
23+
}
24+
25+
@Test
26+
public void testConstructors() {
27+
PImage img1 = new PImage();
28+
assertEquals(PConstants.ARGB, img1.format);
29+
30+
PImage img2 = new PImage(20, 30);
31+
assertEquals(20, img2.width);
32+
assertEquals(30, img2.height);
33+
assertEquals(PConstants.RGB, img2.format);
34+
35+
PImage img3 = new PImage(20, 30, PConstants.ALPHA);
36+
assertEquals(PConstants.ALPHA, img3.format);
37+
38+
PImage img4 = new PImage(20, 30, PConstants.RGB, 2);
39+
assertEquals(2, img4.pixelDensity);
40+
assertEquals(40, img4.pixelWidth);
41+
assertEquals(60, img4.pixelHeight);
42+
43+
PImage zeroImg = new PImage(0, 0);
44+
assertEquals(0, zeroImg.width);
45+
assertEquals(0, zeroImg.height);
46+
assertEquals(0, zeroImg.pixels.length);
47+
}
48+
49+
@Test
50+
public void testPixelManipulation() {
51+
img.loadPixels();
52+
img.pixels[0] = 0xFFFF0000;
53+
img.updatePixels();
54+
assertEquals(0xFFFF0000, img.get(0, 0));
55+
56+
assertEquals(0xFFFF0000, img.get(0, 0));
57+
assertEquals(0, img.get(-1, -1));
58+
assertEquals(0, img.get(100, 100));
59+
60+
img.set(1, 1, 0xFF00FF00);
61+
assertEquals(0xFF00FF00, img.get(1, 1));
62+
63+
img.set(-1, -1, 0xFFFFFFFF);
64+
img.set(100, 100, 0xFFFFFFFF);
65+
66+
PImage region = img.get(0, 0, 2, 2);
67+
assertEquals(2, region.width);
68+
assertEquals(2, region.height);
69+
assertEquals(0xFFFF0000, region.get(0, 0));
70+
assertEquals(0xFF00FF00, region.get(1, 1));
71+
72+
PImage copy = img.get();
73+
assertEquals(img.width, copy.width);
74+
assertEquals(img.height, copy.height);
75+
assertEquals(0xFFFF0000, copy.get(0, 0));
76+
assertEquals(0xFF00FF00, copy.get(1, 1));
77+
78+
PImage negCopy = img.get(-5, -5, 20, 20);
79+
assertEquals(20, negCopy.width);
80+
assertEquals(20, negCopy.height);
81+
}
82+
83+
@Test
84+
public void testCopyAndResize() {
85+
PImage copy = img.copy();
86+
assertEquals(img.width, copy.width);
87+
assertEquals(img.height, copy.height);
88+
assertEquals(img.get(0, 0), copy.get(0, 0));
89+
90+
PImage resized = img.copy();
91+
resized.resize(20, 0);
92+
assertEquals(20, resized.width);
93+
assertTrue(resized.height > 0);
94+
95+
PImage resized2 = img.copy();
96+
resized2.resize(20, 15);
97+
assertEquals(20, resized2.width);
98+
assertEquals(15, resized2.height);
99+
100+
img.set(0, 0, 0xFFFF0000);
101+
img.set(1, 0, 0xFF00FF00);
102+
img.set(0, 1, 0xFF0000FF);
103+
img.set(1, 1, 0xFFFFFF00);
104+
105+
PImage dest = new PImage(4, 4, PConstants.ARGB);
106+
dest.copy(img, 0, 0, 2, 2, 0, 0, 4, 4);
107+
108+
int topLeft = dest.get(0, 0);
109+
int topRight = dest.get(3, 0);
110+
int bottomLeft = dest.get(0, 3);
111+
int bottomRight = dest.get(3, 3);
112+
113+
assertTrue((topLeft & 0x00FF0000) > 0);
114+
assertTrue((topRight & 0x0000FF00) > 0);
115+
assertTrue((bottomLeft & 0x000000FF) > 0);
116+
assertTrue((bottomRight & 0x00FFFF00) > 0);
117+
118+
PImage smallImg = new PImage(5, 5, PConstants.ARGB);
119+
smallImg.copy(img, 0, 0, 10, 10, 0, 0, 5, 5);
120+
img.copy(smallImg, 0, 0, 5, 5, 0, 0, 10, 10);
121+
}
122+
123+
@Test
124+
public void testMask() {
125+
PImage mask = new PImage(10, 10, PConstants.ALPHA);
126+
for (int i = 0; i < mask.pixels.length; i++) {
127+
mask.pixels[i] = (i * 255) / mask.pixels.length;
128+
}
129+
mask.updatePixels();
130+
131+
PImage original = img.copy();
132+
img.mask(mask);
133+
134+
assertTrue((img.get(0, 0) >>> 24) < 10);
135+
136+
assertTrue((img.get(9, 9) >>> 24) > 240);
137+
138+
img = original.copy();
139+
img.mask(mask.pixels);
140+
141+
assertTrue((img.get(0, 0) >>> 24) < 10);
142+
143+
assertTrue((img.get(9, 9) >>> 24) > 240);
144+
145+
PImage smallMask = new PImage(5, 5);
146+
try {
147+
img.mask(smallMask.pixels);
148+
fail("Should throw IllegalArgumentException for wrong size mask");
149+
} catch (IllegalArgumentException e) {
150+
}
151+
}
152+
153+
@Test
154+
public void testFilter() {
155+
for (int i = 0; i < img.pixels.length; i++) {
156+
img.pixels[i] = 0xFF808080;
157+
}
158+
img.updatePixels();
159+
160+
PImage thresholdImg = img.copy();
161+
thresholdImg.filter(PConstants.THRESHOLD, 0.7f);
162+
int thresholdColor = thresholdImg.get(0, 0);
163+
assertTrue((thresholdColor & 0x00FFFFFF) < 0x00808080);
164+
165+
thresholdImg = img.copy();
166+
thresholdImg.filter(PConstants.THRESHOLD, 0.3f);
167+
thresholdColor = thresholdImg.get(0, 0);
168+
assertTrue((thresholdColor & 0x00FFFFFF) > 0x00808080);
169+
170+
PImage grayImg = img.copy();
171+
grayImg.filter(PConstants.GRAY);
172+
int grayColor = grayImg.get(0, 0);
173+
int r = (grayColor >> 16) & 0xFF;
174+
int g = (grayColor >> 8) & 0xFF;
175+
int b = grayColor & 0xFF;
176+
assertEquals(r, g, 5);
177+
assertEquals(g, b, 5);
178+
179+
PImage invertImg = img.copy();
180+
invertImg.filter(PConstants.INVERT);
181+
int originalColor = img.get(0, 0) & 0x00FFFFFF;
182+
int invertedColor = invertImg.get(0, 0) & 0x00FFFFFF;
183+
assertTrue(originalColor + invertedColor > 0x00FFFFFF - 10 &&
184+
originalColor + invertedColor < 0x00FFFFFF + 10);
185+
186+
PImage posterizeImg = img.copy();
187+
posterizeImg.filter(PConstants.POSTERIZE, 2);
188+
189+
PImage blurImg = img.copy();
190+
blurImg.filter(PConstants.BLUR, 1.0f);
191+
192+
img.pixels[0] = 0x80808080;
193+
img.updatePixels();
194+
PImage opaqueImg = img.copy();
195+
opaqueImg.filter(PConstants.OPAQUE);
196+
assertTrue((opaqueImg.get(0, 0) >>> 24) > (img.get(0, 0) >>> 24));
197+
198+
PImage img2 = new PImage(10, 10, PConstants.RGB);
199+
for (int y = 0; y < img2.height; y++) {
200+
for (int x = 0; x < img2.width; x++) {
201+
img2.pixels[y * img2.width + x] = (x == 5 || y == 5) ? 0xFFFFFFFF : 0xFF000000;
202+
}
203+
}
204+
img2.updatePixels();
205+
206+
PImage erodeImg = img2.copy();
207+
erodeImg.filter(PConstants.ERODE);
208+
209+
PImage dilateImg = img2.copy();
210+
dilateImg.filter(PConstants.DILATE);
211+
212+
int blackPixelsInOriginal = 0;
213+
int blackPixelsInDilated = 0;
214+
for (int i = 0; i < img2.pixels.length; i++) {
215+
if ((img2.pixels[i] & 0x00FFFFFF) == 0) blackPixelsInOriginal++;
216+
if ((dilateImg.pixels[i] & 0x00FFFFFF) == 0) blackPixelsInDilated++;
217+
}
218+
assertTrue(blackPixelsInDilated < blackPixelsInOriginal);
219+
}
220+
221+
@Test
222+
public void testAllBlendModesExactMatchStaticHelper() {
223+
final int W = 10, H = 10;
224+
final int red = 0x80FF0000;
225+
final int blue = 0x400000FF;
226+
227+
PImage img1 = new PImage(W, H, PConstants.ARGB);
228+
PImage img2 = new PImage(W, H, PConstants.ARGB);
229+
Arrays.fill(img1.pixels, red);
230+
Arrays.fill(img2.pixels, blue);
231+
img1.updatePixels();
232+
img2.updatePixels();
233+
234+
int[] modes = {
235+
PConstants.BLEND, PConstants.ADD, PConstants.SUBTRACT, PConstants.LIGHTEST,
236+
PConstants.DARKEST, PConstants.DIFFERENCE, PConstants.EXCLUSION,
237+
PConstants.MULTIPLY, PConstants.SCREEN, PConstants.REPLACE
238+
};
239+
240+
for (int mode : modes) {
241+
PImage out = img1.copy();
242+
out.blend(img2, 0,0,W,H, 0,0,W,H, mode);
243+
out.loadPixels();
244+
245+
int[] expected = new int[W*H];
246+
for (int i = 0; i < expected.length; i++) {
247+
expected[i] = (mode == PConstants.REPLACE)
248+
? img2.pixels[i]
249+
: PImage.blendColor(img1.pixels[i], img2.pixels[i], mode);
250+
}
251+
252+
for (int i = 0; i < expected.length; i++) {
253+
assertEquals(
254+
String.format("Mode %d failed at pixel %d: got 0x%08X, expected 0x%08X",
255+
mode, i, out.pixels[i], expected[i]),
256+
expected[i], out.pixels[i]
257+
);
258+
}
259+
}
260+
}
261+
262+
263+
@Test
264+
public void testSaveAndLoad_pngRoundTrip() throws IOException {
265+
PImage out = new PImage(10, 10, PConstants.ARGB);
266+
for (int y = 0; y < out.height; y++) {
267+
for (int x = 0; x < out.width; x++) {
268+
out.pixels[y*out.width + x] =
269+
((x + y) % 2 == 0)
270+
? 0xFFFFFFFF
271+
: 0xFF000000;
272+
}
273+
}
274+
out.updatePixels();
275+
out.parent = applet;
276+
277+
File f = File.createTempFile("test", ".png");
278+
f.deleteOnExit();
279+
assertTrue(out.save(f.getAbsolutePath()));
280+
281+
PImage in = applet.loadImage(f.getAbsolutePath());
282+
assertNotNull(in);
283+
assertEquals(out.width, in.width);
284+
assertEquals(out.height, in.height);
285+
286+
in.loadPixels();
287+
for (int i = 0; i < out.pixels.length; i++) {
288+
assertEquals(
289+
String.format(
290+
"Pixel %d mismatch: saved=0x%08X loaded=0x%08X",
291+
i, out.pixels[i], in.pixels[i]
292+
),
293+
out.pixels[i],
294+
in.pixels[i]
295+
);
296+
}
297+
}
298+
299+
300+
@Test
301+
public void testCheckAlpha() {
302+
PImage opaqueImg = new PImage(5, 5, PConstants.RGB);
303+
for (int i = 0; i < opaqueImg.pixels.length; i++) {
304+
opaqueImg.pixels[i] = 0xFFFFFFFF;
305+
}
306+
opaqueImg.checkAlpha();
307+
assertEquals(PConstants.RGB, opaqueImg.format);
308+
309+
PImage transImg = new PImage(5, 5, PConstants.RGB);
310+
for (int i = 0; i < transImg.pixels.length; i++) {
311+
transImg.pixels[i] = 0x80FFFFFF;
312+
}
313+
transImg.checkAlpha();
314+
assertEquals(PConstants.ARGB, transImg.format);
315+
}
316+
317+
}

0 commit comments

Comments
 (0)