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