Clover icon

Magnolia Imaging Module 3.4.2-SUPPORT-10161

  1. Project Clover database Tue Jul 16 2019 23:33:19 EEST
  2. Package info.magnolia.imaging.util

File ImageUtilTest.java

 

Code metrics

22
100
15
1
357
235
26
0.26
6.67
15
1.73
17% of code in this file is excluded from these metrics.

Classes

Class Line # Actions
ImageUtilTest 62 100 17% 26 4
0.970802997.1%
 

Contributing tests

This file is covered by 17 tests. .

Source view

1    /**
2    * This file Copyright (c) 2009-2018 Magnolia International
3    * Ltd. (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10    * This file is distributed in the hope that it will be
11    * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12    * implied warranty of MERCHANTABILITY or FITNESS FOR A
13    * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14    * Redistribution, except as permitted by whichever of the GPL
15    * or MNA you select, is prohibited.
16    *
17    * 1. For the GPL license (GPL), you can redistribute and/or
18    * modify this file under the terms of the GNU General
19    * Public License, Version 3, as published by the Free Software
20    * Foundation. You should have received a copy of the GNU
21    * General Public License, Version 3 along with this program;
22    * if not, write to the Free Software Foundation, Inc., 51
23    * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24    *
25    * 2. For the Magnolia Network Agreement (MNA), this file
26    * and the accompanying materials are made available under the
27    * terms of the MNA which accompanies this distribution, and
28    * is available at http://www.magnolia-cms.com/mna.html
29    *
30    * Any modifications to this file must keep this entire header
31    * intact.
32    *
33    */
34    package info.magnolia.imaging.util;
35   
36    import static org.junit.Assert.assertEquals;
37    import static org.mockito.Mockito.*;
38   
39    import info.magnolia.imaging.AbstractImagingTest;
40    import info.magnolia.imaging.operations.ImageOperationChain;
41    import info.magnolia.imaging.operations.cropresize.AutoCropAndResize;
42    import info.magnolia.imaging.operations.load.Blank;
43    import info.magnolia.imaging.operations.load.ClasspathImageLoader;
44    import info.magnolia.imaging.operations.load.DefaultImageIOImageDecoder;
45    import info.magnolia.imaging.operations.load.ImageDecoder;
46    import info.magnolia.imaging.operations.text.FixedText;
47    import info.magnolia.imaging.operations.text.TextStyle;
48   
49    import java.awt.Color;
50    import java.awt.Graphics2D;
51    import java.awt.Rectangle;
52    import java.awt.image.BufferedImage;
53    import java.awt.image.ColorModel;
54    import java.awt.image.IndexColorModel;
55    import java.net.URL;
56   
57    import javax.imageio.ImageIO;
58   
59    import org.junit.Before;
60    import org.junit.Test;
61   
 
62    public class ImageUtilTest extends AbstractImagingTest {
63   
64    // not exactly sure what differentiates this jpeg yet - but DefaultImageIOImageDecoder (with the help of the 12monkeys plugins) handles it correctly for us
65    // while the imageio's built-in jpeg support will only "work" if we pass the image's metadata back to the write (which is not
66    // practical since we might want to overlay another image on top for instance)
67   
68    private BufferedImage bufferedImage;
69   
 
70  17 toggle @Before
71    public void setup() {
72  17 bufferedImage = mock(BufferedImage.class);
73    }
74   
 
75  1 toggle @Test
76    public void huffmanImageDecoding() throws Exception {
77  1 final ImageOperationChain chain = chainWithLoaderTextAndResize(new DefaultImageIOImageDecoder(), "/huffman.jpg");
78  1 final BufferedImage res = chain.generate(null);
79  1 final BufferedImage flat = ImageUtil.flattenTransparentImageForOpaqueFormat(res, BASIC_JPEG);
80  1 write("huffman_flat", flat, BASIC_JPEG);
81    }
82   
 
83  1 toggle private ImageOperationChain chainWithLoaderTextAndResize(ImageDecoder imageDecoder, String src) {
84  1 final ClasspathImageLoader loader = new ClasspathImageLoader(src);
85  1 loader.setImageDecoder(imageDecoder);
86   
87  1 final ImageOperationChain chain = new ImageOperationChain();
88  1 chain.addOperation(loader);
89  1 final FixedText text = new FixedText();
90  1 text.setText(imageDecoder.getClass().getName());
91  1 text.setTextStyle(new TextStyle());
92  1 text.getTextStyle().setColor(Color.RED);
93  1 text.getTextStyle().setFontName("Arial");
94  1 text.getTextStyle().setFontSize(20);
95  1 chain.addOperation(text);
96   
97  1 final AutoCropAndResize resize = new AutoCropAndResize();
98  1 resize.setTargetHeight(200);
99  1 resize.setTargetWidth(200);
100  1 chain.addOperation(resize);
101   
102  1 return chain;
103    }
104   
 
105  1 toggle @Test
106    public void canHandleImageCreatedByBlankOperationWithoutBackgroundColor() throws Exception {
107  1 final Blank blank = new Blank(200, 200);
108  1 final BufferedImage img = blank.apply(null, null);
109  1 final BufferedImage res = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
110    // turns out black, this is ok
111  1 write(res, BASIC_JPEG);
112    }
113   
 
114  1 toggle @Test
115    public void canHandleImageCreatedByBlankOperationWithBackgroundColor() throws Exception {
116  1 final Blank blank = new Blank(Color.orange, 200, 200);
117  1 final BufferedImage img = blank.apply(null, null);
118  1 final BufferedImage res = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
119    // should turn out green
120  1 write(res, BASIC_JPEG);
121    }
122   
 
123  1 toggle @Test
124    public void canHandleOpaqueGIFSourceWhenFlatteningForJPEG() throws Exception {
125  1 doFlattenTransparentImageForOpaqueFormat("/some_opaque.gif");
126    }
127   
 
128  1 toggle @Test
129    public void canHandleTransparentGIFSourceWhenFlatteningForJPEG() throws Exception {
130  1 doFlattenTransparentImageForOpaqueFormat("/cookies.gif");
131    }
132   
 
133  1 toggle @Test
134    public void canHandleOpaquePNGSourceWhenFlatteningForJPEG() throws Exception {
135  1 doFlattenTransparentImageForOpaqueFormat("/random_screenshot.png");
136    }
137   
 
138  1 toggle @Test
139    public void canHandleTransparentPNGSourceWhenFlatteningForJPEG() throws Exception {
140  1 doFlattenTransparentImageForOpaqueFormat("/some_transparent.png");
141    }
142   
 
143  1 toggle @Test
144    public void canHandleTranslucentPNGSourceWhenFlatteningForJPEG() throws Exception {
145  1 doFlattenTransparentImageForOpaqueFormat("/pngtrans/rgba16.png");
146    }
147   
 
148  1 toggle @Test
149    /**
150    * An unknown issue with this file 'magnolia-logo.png', causes normal path of flattenTransparentImageForOpaqueFormat to fail,
151    * this test ensures that it successfully applies the fallback of fillTransparentPixels without causing an exception.
152    * @throws Exception
153    */
154    public void canHandleProblematicLogoPNGSourceWhenFlatteningForJPEG() throws Exception {
155  1 doFlattenTransparentImageForOpaqueFormat("/magnolia-logo.png");
156    }
157   
 
158  6 toggle private void doFlattenTransparentImageForOpaqueFormat(final String source) throws Exception {
159    /*
160    * debug print outs
161    * final BufferedImage src = ImageIO.read(getClass().getResourceAsStream(source));
162    * final boolean isOpaque = src.getTransparency() == Transparency.OPAQUE;
163    * final int numBands = src.getRaster().getNumBands();
164    * System.out.println(source + " isOpaque: " + isOpaque);
165    * System.out.println(StringUtils.repeat(" ", source.length()) + " numBands: " + numBands);
166    */
167   
168  6 final BufferedImage img = loadFromResource(source);
169  6 final BufferedImage res = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
170  6 write(res, BASIC_JPEG);
171    }
172   
173    /**
174    * A test case that shows something odd with the jpeg encoder when saving a transparent image.
175    */
 
176  1 toggle @Test
177    public void testJpegOddity() throws Exception {
178    // create a transparent image of 300x300 pixels
179  1 final BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
180   
181    // fill in a small red rectangle in the top right corner
182  1 final Graphics2D g = img.createGraphics();
183  1 g.setColor(Color.red);
184  1 g.fill(new Rectangle(10, 10, 30, 30));
185   
186    // save it - that the background is pinkish, well, why not, but our small square is .. black !?
187  1 write("withoutHack", img, BASIC_JPEG);
188   
189    // now use our workaround and compare results !
190  1 final BufferedImage flattened = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
191  1 write("flattenTransparentImageForOpaqueFormat", flattened, BASIC_JPEG);
192   
193    // use other workaround to see
194  1 final BufferedImage filled = ImageUtil.fillTransparentPixels(img, Color.green);
195  1 write("fillTransparentPixels", filled, BASIC_JPEG);
196    }
197   
 
198  1 toggle @Test
199    public void performance() throws Exception {
200  1 final Blank blank = new Blank(200, 200);
201  1 final BufferedImage src = blank.apply(null, null);
202  1 final int iterations = 1;
203    {
204  1 final long start = System.currentTimeMillis();
205  2 for (int i = 0; i < iterations; i++) {
206  1 ImageUtil.flattenTransparentImageForOpaqueFormat(src, BASIC_JPEG);
207    }
208  1 System.out.println("flattenTransparentImageForOpaqueFormat: " + (System.currentTimeMillis() - start) + "ms.");
209    }
210    {
211  1 final long start = System.currentTimeMillis();
212  2 for (int i = 0; i < iterations; i++) {
213  1 ImageUtil.fillTransparentPixels(src, Color.black);
214    }
215  1 System.out.println("fillTransparentPixels : " + (System.currentTimeMillis() - start) + "ms.");
216    }
217    }
218   
 
219  1 toggle @Test
220    public void loadingPerformance() throws Exception {
221  1 final URL smallPng = getClass().getResource("/pngtrans/rgba16.png");
222  1 final URL largeJpeg = getClass().getResource("/IMG_1937.JPG");
223  1 final int iterations = 1;
224    {
225  1 final long start = System.currentTimeMillis();
226  2 for (int i = 0; i < iterations; i++) {
227  1 ImageIO.read(smallPng);
228    }
229  1 System.out.println("warm up : " + (System.currentTimeMillis() - start) + "ms.");
230    }
231    {
232  1 final long start = System.currentTimeMillis();
233  2 for (int i = 0; i < iterations; i++) {
234  1 ImageIO.read(largeJpeg);
235    }
236  1 System.out.println("warm up 2 : " + (System.currentTimeMillis() - start) + "ms.");
237    }
238    {
239  1 final long start = System.currentTimeMillis();
240  2 for (int i = 0; i < iterations; i++) {
241  1 ImageIO.read(smallPng);
242    }
243  1 System.out.println("just reading small png : " + (System.currentTimeMillis() - start) + "ms.");
244    }
245    {
246  1 final long start = System.currentTimeMillis();
247  2 for (int i = 0; i < iterations; i++) {
248  1 ImageIO.read(largeJpeg);
249    }
250  1 System.out.println("just reading large jpeg : " + (System.currentTimeMillis() - start) + "ms.");
251    }
252    {
253  1 final long start = System.currentTimeMillis();
254  2 for (int i = 0; i < iterations; i++) {
255  1 final BufferedImage src = ImageIO.read(smallPng);
256   
257  1 final BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
258  1 final Graphics2D g = img.createGraphics();
259  1 final boolean b = g.drawImage(src, null, null);
260  1 if (!b) {
261  0 throw new IllegalStateException("wtf?");
262    }
263    }
264  1 System.out.println("with drawing on new image - small png : " + (System.currentTimeMillis() - start) + "ms.");
265    }
266    {
267  1 final long start = System.currentTimeMillis();
268  2 for (int i = 0; i < iterations; i++) {
269  1 final BufferedImage src = ImageIO.read(largeJpeg);
270   
271  1 final BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
272  1 final Graphics2D g = img.createGraphics();
273  1 final boolean b = g.drawImage(src, null, null);
274  1 if (!b) {
275  0 throw new IllegalStateException("wtf?");
276    }
277    }
278  1 System.out.println("with drawing on new image - large jpeg: " + (System.currentTimeMillis() - start) + "ms.");
279    }
280    {
281  1 final long start = System.currentTimeMillis();
282  2 for (int i = 0; i < iterations; i++) {
283  1 final ClasspathImageLoader loader = new ClasspathImageLoader("/IMG_1937.JPG");
284  1 loader.apply(null, null);
285    }
286  1 System.out.println("with ClasspathImageLoader - large jpeg: " + (System.currentTimeMillis() - start) + "ms.");
287    }
288    }
289   
 
290    toggle @Test
291    public void getOriginalImageType() throws Exception {
292    // GIVEN
293    BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
294   
295    // WHEN
296    int imageType = ImageUtil.getImageType(img);
297   
298    // THEN
299    assertEquals(BufferedImage.TYPE_3BYTE_BGR, imageType);
300    }
301   
 
302    toggle @Test
303    public void getImageTypeIndexedTypeWithoutAlpha() throws Exception {
304    // GIVEN
305    ColorModel colorModel = new IndexColorModel(1, 1, new byte[8], 0, false);
306    when(bufferedImage.getType()).thenReturn(BufferedImage.TYPE_BYTE_INDEXED);
307    when(bufferedImage.getColorModel()).thenReturn(colorModel);
308   
309    // WHEN
310    int imageType = ImageUtil.getImageType(bufferedImage);
311   
312    // THEN
313    assertEquals(BufferedImage.TYPE_INT_RGB, imageType);
314    }
315   
 
316    toggle @Test
317    public void getImageTypeIndexedTypeWithAlpha() throws Exception {
318    // GIVEN
319    ColorModel colorModel = new IndexColorModel(1, 1, new byte[8], 0, true);
320    when(bufferedImage.getType()).thenReturn(BufferedImage.TYPE_BYTE_INDEXED);
321    when(bufferedImage.getColorModel()).thenReturn(colorModel);
322   
323    // WHEN
324    int imageType = ImageUtil.getImageType(bufferedImage);
325   
326    // THEN
327    assertEquals(BufferedImage.TYPE_INT_ARGB_PRE, imageType);
328    }
329   
 
330    toggle @Test
331    public void getImageTypeByteBinaryWithoutAlpha() throws Exception {
332    // GIVEN
333    ColorModel colorModel = new IndexColorModel(1, 1, new byte[8], 0, false);
334    when(bufferedImage.getType()).thenReturn(BufferedImage.TYPE_BYTE_BINARY);
335    when(bufferedImage.getColorModel()).thenReturn(colorModel);
336   
337    // WHEN
338    int imageType = ImageUtil.getImageType(bufferedImage);
339   
340    // THEN
341    assertEquals(BufferedImage.TYPE_INT_RGB, imageType);
342    }
343   
 
344    toggle @Test
345    public void getImageTypeByteBinaryWithAlpha() throws Exception {
346    // GIVEN
347    ColorModel colorModel = new IndexColorModel(1, 1, new byte[8], 0, true);
348    when(bufferedImage.getType()).thenReturn(BufferedImage.TYPE_BYTE_BINARY);
349    when(bufferedImage.getColorModel()).thenReturn(colorModel);
350   
351    // WHEN
352    int imageType = ImageUtil.getImageType(bufferedImage);
353   
354    // THEN
355    assertEquals(BufferedImage.TYPE_INT_ARGB_PRE, imageType);
356    }
357    }