1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.galleryimage.util;
35
36 import org.apache.commons.fileupload.FileItem;
37 import org.apache.commons.fileupload.FileItemFactory;
38 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
39 import org.apache.commons.imaging.ImageInfo;
40 import org.apache.commons.imaging.ImageParser;
41 import org.apache.commons.imaging.Imaging;
42 import org.apache.commons.imaging.formats.bmp.BmpImageParser;
43 import org.apache.commons.imaging.formats.dcx.DcxImageParser;
44 import org.apache.commons.imaging.formats.gif.GifImageParser;
45 import org.apache.commons.imaging.formats.pcx.PcxImageParser;
46 import org.apache.commons.imaging.formats.png.PngImageParser;
47 import org.apache.commons.imaging.formats.tiff.TiffImageParser;
48 import org.apache.commons.imaging.formats.wbmp.WbmpImageParser;
49 import org.apache.commons.imaging.formats.xbm.XbmImageParser;
50 import org.apache.commons.imaging.formats.xpm.XpmImageParser;
51 import org.apache.commons.lang3.StringUtils;
52 import org.imgscalr.Scalr;
53
54 import fr.paris.lutece.portal.service.image.ImageResource;
55 import fr.paris.lutece.portal.service.util.AppLogService;
56
57 import java.awt.Graphics;
58 import java.awt.Image;
59 import java.awt.image.BufferedImage;
60
61 import java.io.ByteArrayOutputStream;
62 import java.io.IOException;
63 import java.io.OutputStream;
64 import java.util.Base64;
65 import java.util.Iterator;
66
67 import javax.imageio.ImageIO;
68 import javax.imageio.ImageReader;
69 import javax.imageio.stream.ImageInputStream;
70
71
72
73
74 public final class ImageUtils
75 {
76
77 private static final String PARAMETER_JPG = "jpg";
78
79
80
81
82 private ImageUtils( )
83 {
84 }
85
86
87
88
89
90
91
92
93 public static FileItem resizeImage( FileItem fileItem, int width )
94 {
95
96 try
97 {
98 ByteArrayOutputStream out = new ByteArrayOutputStream( );
99 BufferedImage image = ImageIO.read( fileItem.getInputStream( ) );
100 BufferedImage resizedImage = Scalr.resize( image, Scalr.Mode.FIT_TO_WIDTH, width );
101 ImageIO.write( resizedImage, PARAMETER_JPG, out );
102
103 return createFileItem( out.toByteArray( ), fileItem.getFieldName( ), fileItem.getContentType( ), fileItem.getName( ) );
104 }
105 catch( Exception e )
106 {
107 AppLogService.error( "ImageUtils:resizeImage( ): {} ", e.getMessage( ), e );
108 }
109 return fileItem;
110 }
111
112
113
114
115 private static FileItem createFileItem( byte [ ] contentBytes, String strFieldName, String strContentType, String strFileName )
116 {
117 FileItemFactory factory = new DiskFileItemFactory( );
118 FileItem item = factory.createItem( strFieldName, strContentType, false, strFileName );
119
120 try
121 {
122 OutputStream os = item.getOutputStream( );
123 os.write( contentBytes );
124 os.close( );
125 }
126 catch( IOException e )
127 {
128 AppLogService.error( "ImageUtils:createFileItem( ): {} ", e.getMessage( ), e );
129 }
130 return item;
131 }
132
133
134
135
136
137
138
139 public static boolean safeImage( FileItem fileItem )
140 {
141 boolean safeState = false;
142 boolean fallbackOnApacheCommonsImaging;
143 try
144 {
145 if ( fileItem != null )
146 {
147
148 String formatName;
149 try ( ImageInputStream iis = ImageIO.createImageInputStream( fileItem.getInputStream( ) ) )
150 {
151 Iterator<ImageReader> imageReaderIterator = ImageIO.getImageReaders( iis );
152
153
154 if ( !imageReaderIterator.hasNext( ) )
155 {
156 ImageInfo imageInfo = Imaging.getImageInfo( fileItem.get( ) );
157 if ( imageInfo != null && imageInfo.getFormat( ) != null && imageInfo.getFormat( ).getName( ) != null )
158 {
159 formatName = imageInfo.getFormat( ).getName( );
160 fallbackOnApacheCommonsImaging = true;
161 }
162 else
163 {
164 throw new IOException( "Format of the original image is " + "not supported for read operation !" );
165 }
166 }
167 else
168 {
169 ImageReader reader = imageReaderIterator.next( );
170 formatName = reader.getFormatName( );
171 fallbackOnApacheCommonsImaging = false;
172 }
173 }
174
175
176 BufferedImage originalImage;
177 if ( !fallbackOnApacheCommonsImaging )
178 {
179 originalImage = ImageIO.read( fileItem.getInputStream( ) );
180 }
181 else
182 {
183 originalImage = Imaging.getBufferedImage( fileItem.getInputStream( ) );
184 }
185
186
187 if ( originalImage == null )
188 {
189 throw new IOException( "Cannot load the original image !" );
190 }
191
192
193 int originalWidth = originalImage.getWidth( null );
194 int originalHeight = originalImage.getHeight( null );
195
196
197 Image resizedImage = originalImage.getScaledInstance( originalWidth - 1, originalHeight - 1, Image.SCALE_SMOOTH );
198
199
200
201 Image initialSizedImage = resizedImage.getScaledInstance( originalWidth, originalHeight, Image.SCALE_SMOOTH );
202
203
204 BufferedImage sanitizedImage = new BufferedImage( initialSizedImage.getWidth( null ), initialSizedImage.getHeight( null ),
205 BufferedImage.TYPE_INT_RGB );
206 Graphics bg = sanitizedImage.getGraphics( );
207 bg.drawImage( initialSizedImage, 0, 0, null );
208 bg.dispose( );
209
210 try ( OutputStream fos = new ByteArrayOutputStream( ) )
211 {
212 if ( !fallbackOnApacheCommonsImaging )
213 {
214 ImageIO.write( sanitizedImage, formatName, fos );
215 }
216 else
217 {
218 ImageParser imageParser;
219
220
221
222 switch( formatName )
223 {
224 case "TIFF":
225 {
226 imageParser = new TiffImageParser( );
227 break;
228 }
229 case "PCX":
230 {
231 imageParser = new PcxImageParser( );
232 break;
233 }
234 case "DCX":
235 {
236 imageParser = new DcxImageParser( );
237 break;
238 }
239 case "BMP":
240 {
241 imageParser = new BmpImageParser( );
242 break;
243 }
244 case "GIF":
245 {
246 imageParser = new GifImageParser( );
247 break;
248 }
249 case "PNG":
250 {
251 imageParser = new PngImageParser( );
252 break;
253 }
254 case "WBMP":
255 {
256 imageParser = new WbmpImageParser( );
257 break;
258 }
259 case "XBM":
260 {
261 imageParser = new XbmImageParser( );
262 break;
263 }
264 case "XPM":
265 {
266 imageParser = new XpmImageParser( );
267 break;
268 }
269 default:
270 {
271 throw new IOException( "Format of the original image is not" + " supported for write operation !" );
272 }
273
274 }
275 imageParser.writeImage( sanitizedImage, fos, null );
276 }
277
278 }
279
280
281 safeState = true;
282 }
283 }
284 catch( Exception e )
285 {
286 safeState = false;
287 AppLogService.error( "Error during Image file processing ! {}", e.getMessage( ), e );
288 }
289
290 return safeState;
291 }
292
293
294
295
296
297
298 public static String imageBase64 ( ImageResource imageResource )
299 {
300 if ( imageResource != null )
301 {
302 return "data:" + imageResource.getMimeType( ) + ";base64," + Base64.getEncoder( ).encodeToString( imageResource.getImage( ) );
303 }
304 return StringUtils.EMPTY;
305 }
306 }