1 /*
2 * Copyright (c) 2002-2016, Mairie de Paris
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice
10 * and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice
13 * and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 * License 1.0
33 */
34 package fr.paris.lutece.plugins.avatarserver.service;
35
36 import fr.paris.lutece.portal.service.util.AppLogService;
37
38 import org.imgscalr.Scalr;
39
40 import java.awt.image.BufferedImage;
41 import java.awt.Color;
42
43 import java.io.ByteArrayInputStream;
44 import java.io.ByteArrayOutputStream;
45 import java.io.IOException;
46
47 import javax.imageio.IIOImage;
48 import javax.imageio.ImageIO;
49 import javax.imageio.ImageWriteParam;
50 import javax.imageio.ImageWriter;
51 import javax.imageio.stream.MemoryCacheImageOutputStream;
52
53 /**
54 * Image Service
55 */
56 public final class ImageService
57 {
58 /** Parameter JPG */
59 private static final String PARAMETER_JPG = "jpg";
60
61 /** Private constructor */
62 private ImageService( )
63 {
64 }
65
66 /**
67 * Resize an image with the default quality
68 *
69 * @param byteArray
70 * the original byte array
71 * @param width
72 * the new width
73 * @return the resize byte array
74 */
75 public static byte [ ] resizeImage( byte [ ] byteArray, int width )
76 {
77 return resizeImage( byteArray, width, AvatarService.getQuality( ) );
78 }
79
80 /**
81 * Resize an image
82 *
83 * @param byteArray
84 * the original byte array
85 * @param width
86 * the new width
87 * @param quality
88 * the quality between 0.0 and 1.0
89 * @return the resize byte array
90 */
91 public static byte [ ] resizeImage( byte [ ] byteArray, int width, float quality )
92 {
93 try
94 {
95 // Crop image if needed
96 ByteArrayInputStream in = new ByteArrayInputStream( byteArray );
97 ByteArrayOutputStream out = new ByteArrayOutputStream( );
98 BufferedImage image = ImageIO.read( in );
99
100 // Replace transparent background with white and drop alpha channel
101 // Otherwise, the rest of the code would swap channels and this would lead to a red tint on images
102 if ( image.getColorModel( ).hasAlpha( ) )
103 {
104 BufferedImage newImage = new BufferedImage( image.getWidth( ), image.getHeight( ), BufferedImage.TYPE_INT_RGB );
105 newImage.createGraphics( ).drawImage( image, 0, 0, Color.WHITE, null );
106 image = newImage;
107 }
108
109 BufferedImage resizedImage;
110 resizedImage = Scalr.resize( image, Scalr.Mode.FIT_TO_WIDTH, width );
111
112 // Boilerplate to be able to set the quality
113 ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName( PARAMETER_JPG ).next( );
114 ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam( );
115 jpgWriteParam.setCompressionMode( ImageWriteParam.MODE_EXPLICIT );
116 jpgWriteParam.setCompressionQuality( quality );
117 jpgWriter.setOutput( new MemoryCacheImageOutputStream( out ) );
118 IIOImage outputImage = new IIOImage( resizedImage, null, null );
119 jpgWriter.write( null, outputImage, jpgWriteParam );
120 jpgWriter.dispose( );
121 out.flush( );
122
123 return out.toByteArray( );
124 }
125 catch( IOException ex )
126 {
127 AppLogService.error( "Avatar - Image Service - Error resizing image : " + ex.getMessage( ), ex );
128 }
129
130 return byteArray;
131 }
132 }