1 package fr.ifremer.quadrige3.core.dao.technical;
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 import com.google.common.collect.ImmutableList;
27 import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
28 import org.apache.commons.io.FileUtils;
29 import org.apache.commons.io.FilenameUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.imgscalr.Scalr;
33
34 import javax.imageio.ImageIO;
35 import javax.imageio.ImageReader;
36 import javax.imageio.stream.FileImageInputStream;
37 import javax.imageio.stream.ImageInputStream;
38 import java.awt.Dimension;
39 import java.awt.image.BufferedImage;
40 import java.io.File;
41 import java.io.IOException;
42 import java.util.Iterator;
43 import java.util.List;
44
45
46
47
48
49
50 public class Images {
51
52 private static final String JPG_EXTENSION = "jpg";
53 private static final String JPEG_EXTENSION = "jpeg";
54 private static final String PNG_EXTENSION = "png";
55 public static final List<String> AVAILABLE_EXTENSION_LIST = ImmutableList.of(JPG_EXTENSION, JPEG_EXTENSION, PNG_EXTENSION);
56
57
58
59 public static final String AVAILABLE_EXTENSION = JPG_EXTENSION + '|' + JPEG_EXTENSION + '|' + PNG_EXTENSION;
60
61 private static final Log LOG = LogFactory.getLog(Images.class);
62
63
64
65
66
67
68
69 public static Dimension getImageDimension(File imageFile) {
70
71 Iterator<ImageReader> iterator = ImageIO.getImageReadersBySuffix(getImageFileExtension(imageFile));
72 if (iterator.hasNext()) {
73 ImageReader reader = iterator.next();
74 try {
75 ImageInputStream stream = new FileImageInputStream(imageFile);
76 reader.setInput(stream);
77 int width = reader.getWidth(reader.getMinIndex());
78 int height = reader.getHeight(reader.getMinIndex());
79 return new Dimension(width, height);
80 } catch (IOException e) {
81 LOG.warn("Error reading: " + imageFile.getAbsolutePath(), e);
82 } finally {
83 reader.dispose();
84 }
85 }
86
87 throw new QuadrigeTechnicalException("Not a known image file: " + imageFile.getAbsolutePath());
88 }
89
90
91
92
93
94
95
96
97 public static File importAndPrepareImageFile(File inputFile, File targetDir) {
98
99 try {
100
101 String baseName = String.format("%s", System.currentTimeMillis());
102 String fileExtension = getImageFileExtension(inputFile);
103
104
105 File bigFile = new File(targetDir, String.format("%s.%s", baseName, fileExtension));
106 FileUtils.copyFile(inputFile, bigFile);
107
108 prepareImageFile(bigFile);
109
110 return bigFile;
111
112 } catch (IOException ioe) {
113
114 throw new QuadrigeTechnicalException(ioe);
115 }
116 }
117
118
119
120
121
122
123 public static void prepareImageFile(File inputFile) {
124
125 String fileExtension = getImageFileExtension(inputFile);
126 try {
127
128
129 BufferedImage bigImage = ImageIO.read(inputFile);
130
131
132 ImageIO.write(Scalr.resize(bigImage, ImageType.DIAPO.getMaxSize()), fileExtension, getMediumImageFile(inputFile));
133
134
135 ImageIO.write(Scalr.resize(bigImage, ImageType.THUMBNAIL.getMaxSize()), fileExtension, getSmallImageFile(inputFile));
136
137 } catch (IOException ioe) {
138
139 throw new QuadrigeTechnicalException(ioe);
140 }
141
142 }
143
144 public static File getMediumImageFile(File baseImageFile) {
145 return getImageFile(baseImageFile, ImageType.DIAPO);
146 }
147
148 public static File getSmallImageFile(File baseImageFile) {
149 return getImageFile(baseImageFile, ImageType.THUMBNAIL);
150 }
151
152 private static File getImageFile(File baseImageFile, ImageType imageType) {
153 return new File(baseImageFile.getParentFile(),
154 String.format("%s%s.%s", getValidBaseName(baseImageFile), imageType.getSuffix(), getImageFileExtension(baseImageFile)));
155 }
156
157
158
159
160
161
162
163
164
165 public static BufferedImage loadImage(File inputFile, ImageType imageType, boolean createIfNotExists) {
166
167 if (!inputFile.exists()) {
168 LOG.warn("the image to load doesn't exist : " + inputFile);
169 return null;
170 }
171
172 File targetFile = getImageFile(inputFile, imageType);
173
174 if (targetFile.exists()) {
175 try {
176 return ImageIO.read(targetFile);
177 } catch (IOException ioe) {
178 throw new QuadrigeTechnicalException(ioe);
179 }
180 } else if (createIfNotExists && imageType != ImageType.BASE) {
181
182 prepareImageFile(inputFile);
183
184 return loadImage(inputFile, imageType, false);
185 }
186
187 return null;
188
189 }
190
191
192
193
194
195
196 public static void deleteImage(File inputFile) {
197
198 getValidBaseName(inputFile);
199
200 FileUtils.deleteQuietly(inputFile);
201
202 deleteOtherImage(inputFile);
203 }
204
205
206
207
208
209
210 public static void deleteOtherImage(File inputFile) {
211 FileUtils.deleteQuietly(getMediumImageFile(inputFile));
212 FileUtils.deleteQuietly(getSmallImageFile(inputFile));
213 }
214
215 private static String getValidBaseName(File inputFile) {
216 String baseName = FilenameUtils.getBaseName(inputFile.getName());
217 if (baseName.endsWith(ImageType.THUMBNAIL.getSuffix()) || baseName.endsWith(ImageType.DIAPO.getSuffix())) {
218 throw new QuadrigeTechnicalException("inputFile name must not have the suffix " + ImageType.THUMBNAIL.getSuffix() + " or " + ImageType.DIAPO.getSuffix());
219 }
220 return baseName;
221 }
222
223 private static String getImageFileExtension(File inputFile) {
224 String fileExtension = FilenameUtils.getExtension(inputFile.getName());
225 if (!AVAILABLE_EXTENSION_LIST.contains(fileExtension.toLowerCase())) {
226 throw new QuadrigeTechnicalException("inputFile is not a '" + AVAILABLE_EXTENSION + "' file");
227 }
228 return fileExtension;
229 }
230
231 public enum ImageType {
232 BASE("", null),
233 DIAPO("$MID", 500),
234 THUMBNAIL("$LOW", 200);
235
236 private final String suffix;
237 private final Integer maxSize;
238
239 ImageType(String suffix, Integer maxSize) {
240 this.suffix = suffix;
241 this.maxSize = maxSize;
242 }
243
244 public String getSuffix() {
245 return suffix;
246 }
247
248 public Integer getMaxSize() {
249 return maxSize;
250 }
251 }
252 }