Clover icon

Magnolia Imaging Module 3.2.3

  1. Project Clover database Fri Nov 6 2015 14:54:03 CET
  2. Package info.magnolia.imaging.util

File ImageUtilTest.java

 

Code metrics

22
116
17
1
329
218
28
0.24
6.82
17
1.65

Classes

Class Line # Actions
ImageUtilTest 65 116 0% 28 4
0.974193697.4%
 

Contributing tests

This file is covered by 15 tests. .

Source view

1    /**
2    * This file Copyright (c) 2009-2015 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.*;
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.io.IOException;
56    import java.net.URL;
57   
58    import javax.imageio.ImageIO;
59   
60    import org.junit.Test;
61   
62    /**
63    * Tests for {@link ImageUtil}.
64    */
 
65    public class ImageUtilTest extends AbstractImagingTest {
66   
67    // not exactly sure what differentiates this jpeg yet - but DefaultImageIOImageDecoder (with the help of the 12monkeys plugins) handles it correctly for us
68    // 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
69    // practical since we might want to overlay another image on top for instance)
 
70  1 toggle @Test
71    public void testDecodingHuffmanImage() throws Exception {
72  1 final ImageOperationChain chain = chainWithLoaderTextAndResize(new DefaultImageIOImageDecoder(), "/huffman.jpg");
73  1 final BufferedImage res = chain.generate(null);
74  1 final BufferedImage flat = ImageUtil.flattenTransparentImageForOpaqueFormat(res, BASIC_JPEG);
75  1 write("huffman_flat", flat, BASIC_JPEG);
76    }
77   
 
78  1 toggle private ImageOperationChain chainWithLoaderTextAndResize(ImageDecoder imageDecoder, String src) {
79  1 final ClasspathImageLoader loader = new ClasspathImageLoader(src);
80  1 loader.setImageDecoder(imageDecoder);
81   
82  1 final ImageOperationChain chain = new ImageOperationChain();
83  1 chain.addOperation(loader);
84  1 final FixedText text = new FixedText();
85  1 text.setText(imageDecoder.getClass().getName());
86  1 text.setTextStyle(new TextStyle());
87  1 text.getTextStyle().setColor(Color.RED);
88  1 text.getTextStyle().setFontName("Arial");
89  1 text.getTextStyle().setFontSize(20);
90  1 chain.addOperation(text);
91   
92  1 final AutoCropAndResize resize = new AutoCropAndResize();
93  1 resize.setTargetHeight(200);
94  1 resize.setTargetWidth(200);
95  1 chain.addOperation(resize);
96   
97  1 return chain;
98    }
99   
 
100  1 toggle @Test
101    public void testCanHandleImageCreatedByBlankOperationWithoutBackgroundColor() throws Exception {
102  1 final Blank blank = new Blank(200, 200);
103  1 final BufferedImage img = blank.apply(null, null);
104  1 final BufferedImage res = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
105    // turns out black, this is ok
106  1 write(res, BASIC_JPEG);
107    }
108   
 
109  1 toggle @Test
110    public void testCanHandleImageCreatedByBlankOperationWithBackgroundColor() throws Exception {
111  1 final Blank blank = new Blank(Color.orange, 200, 200);
112  1 final BufferedImage img = blank.apply(null, null);
113  1 final BufferedImage res = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
114    // should turn out green
115  1 write(res, BASIC_JPEG);
116    }
117   
 
118  1 toggle @Test
119    public void testCanHandleOpaqueGIFSourceWhenFlatteningForJPEG() throws Exception {
120  1 doTestFlattenTransparentImageForOpaqueFormat("/some_opaque.gif");
121    }
122   
 
123  1 toggle @Test
124    public void testCanHandleTransparentGIFSourceWhenFlatteningForJPEG() throws Exception {
125  1 doTestFlattenTransparentImageForOpaqueFormat("/cookies.gif");
126    }
127   
 
128  1 toggle @Test
129    public void testCanHandleOpaquePNGSourceWhenFlatteningForJPEG() throws Exception {
130  1 doTestFlattenTransparentImageForOpaqueFormat("/random_screenshot.png");
131    }
132   
 
133  1 toggle @Test
134    public void testCanHandleTransparentPNGSourceWhenFlatteningForJPEG() throws Exception {
135  1 doTestFlattenTransparentImageForOpaqueFormat("/some_transparent.png");
136    }
137   
 
138  1 toggle @Test
139    public void testCanHandleTranslucentPNGSourceWhenFlatteningForJPEG() throws Exception {
140  1 doTestFlattenTransparentImageForOpaqueFormat("/pngtrans/rgba16.png");
141    }
142   
 
143  1 toggle @Test
144    /**
145    * An unknown issue with this file 'magnolia-logo.png', causes normal path of flattenTransparentImageForOpaqueFormat to fail,
146    * this test ensures that it sucessfully applies the fallback of fillTransparentPixels without causing an exception.
147    * @throws Exception
148    */
149    public void testCanHandleProblematicLogoPNGSourceWhenFlatteningForJPEG() throws Exception {
150  1 doTestFlattenTransparentImageForOpaqueFormat("/magnolia-logo.png");
151    }
152   
 
153  6 toggle private void doTestFlattenTransparentImageForOpaqueFormat(final String source) throws Exception {
154    /*
155    * debug print outs
156    * final BufferedImage src = ImageIO.read(getClass().getResourceAsStream(source));
157    * final boolean isOpaque = src.getTransparency() == Transparency.OPAQUE;
158    * final int numBands = src.getRaster().getNumBands();
159    * System.out.println(source + " isOpaque: " + isOpaque);
160    * System.out.println(StringUtils.repeat(" ", source.length()) + " numBands: " + numBands);
161    */
162   
163  6 final BufferedImage img = loadFromResource(source);
164  6 final BufferedImage res = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
165  6 write(res, BASIC_JPEG);
166    }
167   
168    /**
169    * A test case that shows something odd with the jpeg encoder when saving a transparent image.
170    */
 
171  1 toggle @Test
172    public void testJpegOddity() throws IOException {
173    // create a transparent image of 300x300 pixels
174  1 final BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
175   
176    // fill in a small red rectangle in the top right corner
177  1 final Graphics2D g = img.createGraphics();
178  1 g.setColor(Color.red);
179  1 g.fill(new Rectangle(10, 10, 30, 30));
180   
181    // save it - that the background is pinkish, well, why not, but our small square is .. black !?
182  1 write("withoutHack", img, BASIC_JPEG);
183   
184    // now use our workaround and compare results !
185  1 final BufferedImage flattened = ImageUtil.flattenTransparentImageForOpaqueFormat(img, BASIC_JPEG);
186  1 write("flattenTransparentImageForOpaqueFormat", flattened, BASIC_JPEG);
187   
188    // use other workaround to see
189  1 final BufferedImage filled = ImageUtil.fillTransparentPixels(img, Color.green);
190  1 write("fillTransparentPixels", filled, BASIC_JPEG);
191    }
192   
 
193  1 toggle @Test
194    public void testPerformance() throws Exception {
195  1 final Blank blank = new Blank(200, 200);
196  1 final BufferedImage src = blank.apply(null, null);
197  1 final int iterations = 1;
198    {
199  1 final long start = System.currentTimeMillis();
200  2 for (int i = 0; i < iterations; i++) {
201  1 ImageUtil.flattenTransparentImageForOpaqueFormat(src, BASIC_JPEG);
202    }
203  1 System.out.println("flattenTransparentImageForOpaqueFormat: " + (System.currentTimeMillis() - start) + "ms.");
204    }
205    {
206  1 final long start = System.currentTimeMillis();
207  2 for (int i = 0; i < iterations; i++) {
208  1 ImageUtil.fillTransparentPixels(src, Color.black);
209    }
210  1 System.out.println("fillTransparentPixels : " + (System.currentTimeMillis() - start) + "ms.");
211    }
212    }
213   
 
214  1 toggle @Test
215    public void testLoadingPerformance() throws Exception {
216  1 final URL smallPng = getClass().getResource("/pngtrans/rgba16.png");
217  1 final URL largeJpeg = getClass().getResource("/IMG_1937.JPG");
218  1 final int iterations = 1;
219    {
220  1 final long start = System.currentTimeMillis();
221  2 for (int i = 0; i < iterations; i++) {
222  1 ImageIO.read(smallPng);
223    }
224  1 System.out.println("warm up : " + (System.currentTimeMillis() - start) + "ms.");
225    }
226    {
227  1 final long start = System.currentTimeMillis();
228  2 for (int i = 0; i < iterations; i++) {
229  1 ImageIO.read(largeJpeg);
230    }
231  1 System.out.println("warm up 2 : " + (System.currentTimeMillis() - start) + "ms.");
232    }
233    {
234  1 final long start = System.currentTimeMillis();
235  2 for (int i = 0; i < iterations; i++) {
236  1 ImageIO.read(smallPng);
237    }
238  1 System.out.println("just reading small png : " + (System.currentTimeMillis() - start) + "ms.");
239    }
240    {
241  1 final long start = System.currentTimeMillis();
242  2 for (int i = 0; i < iterations; i++) {
243  1 ImageIO.read(largeJpeg);
244    }
245  1 System.out.println("just reading large jpeg : " + (System.currentTimeMillis() - start) + "ms.");
246    }
247    {
248  1 final long start = System.currentTimeMillis();
249  2 for (int i = 0; i < iterations; i++) {
250  1 final BufferedImage src = ImageIO.read(smallPng);
251   
252  1 final BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
253  1 final Graphics2D g = img.createGraphics();
254  1 final boolean b = g.drawImage(src, null, null);
255  1 if (!b) {
256  0 throw new IllegalStateException("wtf?");
257    }
258    }
259  1 System.out.println("with drawing on new image - small png : " + (System.currentTimeMillis() - start) + "ms.");
260    }
261    {
262  1 final long start = System.currentTimeMillis();
263  2 for (int i = 0; i < iterations; i++) {
264  1 final BufferedImage src = ImageIO.read(largeJpeg);
265   
266  1 final BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
267  1 final Graphics2D g = img.createGraphics();
268  1 final boolean b = g.drawImage(src, null, null);
269  1 if (!b) {
270  0 throw new IllegalStateException("wtf?");
271    }
272    }
273  1 System.out.println("with drawing on new image - large jpeg: " + (System.currentTimeMillis() - start) + "ms.");
274    }
275    {
276  1 final long start = System.currentTimeMillis();
277  2 for (int i = 0; i < iterations; i++) {
278  1 final ClasspathImageLoader loader = new ClasspathImageLoader("/IMG_1937.JPG");
279  1 loader.apply(null, null);
280    }
281  1 System.out.println("with ClasspathImageLoader - large jpeg: " + (System.currentTimeMillis() - start) + "ms.");
282    }
283    }
284   
 
285  1 toggle @Test
286    public void testGetOriginalImageType() throws Exception {
287    // GIVEN
288  1 BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
289   
290    // WHEN
291  1 int imageType = ImageUtil.getImageType(img);
292   
293    // THEN
294  1 assertEquals(BufferedImage.TYPE_3BYTE_BGR, imageType);
295    }
296   
 
297  1 toggle @Test
298    public void testGetImageTypeIndexedTypeWithoutAlpha() throws Exception {
299    // GIVEN
300  1 ColorModel colorModel = new IndexColorModel(1, 1, new byte[8], 0, false);
301  1 assertFalse(colorModel.hasAlpha());
302  1 BufferedImage img = mock(BufferedImage.class);
303  1 when(img.getType()).thenReturn(BufferedImage.TYPE_BYTE_INDEXED);
304  1 when(img.getColorModel()).thenReturn(colorModel);
305   
306    // WHEN
307  1 int imageType = ImageUtil.getImageType(img);
308   
309    // THEN
310  1 assertEquals(BufferedImage.TYPE_BYTE_INDEXED, imageType);
311    }
312   
 
313  1 toggle @Test
314    public void testGetImageTypeIndexedTypeWithAlpha() throws Exception {
315    // GIVEN
316  1 ColorModel colorModel = new IndexColorModel(1, 1, new byte[8], 0, true);
317  1 assertTrue(colorModel.hasAlpha());
318  1 BufferedImage img = mock(BufferedImage.class);
319  1 when(img.getType()).thenReturn(BufferedImage.TYPE_BYTE_INDEXED);
320  1 when(img.getColorModel()).thenReturn(colorModel);
321   
322    // WHEN
323  1 int imageType = ImageUtil.getImageType(img);
324   
325    // THEN
326  1 assertEquals(BufferedImage.TYPE_INT_ARGB_PRE, imageType);
327    }
328   
329    }