add checks on ImageUtils instances
[nikiroo-utils.git] / src / be / nikiroo / utils / ui / ImageUtilsAwt.java
1 package be.nikiroo.utils.ui;
2
3 import java.awt.geom.AffineTransform;
4 import java.awt.image.AffineTransformOp;
5 import java.awt.image.BufferedImage;
6 import java.io.File;
7 import java.io.IOException;
8 import java.io.InputStream;
9
10 import javax.imageio.ImageIO;
11
12 import be.nikiroo.utils.Image;
13 import be.nikiroo.utils.ImageUtils;
14
15 /**
16 * This class offer some utilities based around images and uses java.awt.
17 *
18 * @author niki
19 */
20 public class ImageUtilsAwt extends ImageUtils {
21 @Override
22 protected boolean check() {
23 // If we can get the class, it means we have access to it
24 @SuppressWarnings("unused")
25 Object test = ImageIO.class;
26 return true;
27 }
28
29 @Override
30 public void saveAsImage(Image img, File target, String format)
31 throws IOException {
32 try {
33 BufferedImage image = fromImage(img);
34
35 boolean ok = false;
36 try {
37
38 ok = ImageIO.write(image, format, target);
39 } catch (IOException e) {
40 ok = false;
41 }
42
43 // Some formats are not reliable
44 // Second chance: PNG
45 if (!ok && !format.equals("png")) {
46 try {
47 ok = ImageIO.write(image, "png", target);
48 } catch (IllegalArgumentException e) {
49 throw e;
50 } catch (Exception e) {
51 throw new IOException("Undocumented exception occured, "
52 + "converting to IOException", e);
53 }
54 }
55
56 if (!ok) {
57 throw new IOException(
58 "Cannot find a writer for this image and format: "
59 + format);
60 }
61 } catch (IOException e) {
62 throw new IOException("Cannot write image to " + target, e);
63 }
64 }
65
66 /**
67 * Convert the given {@link Image} into a {@link BufferedImage} object,
68 * respecting the EXIF transformations if any.
69 *
70 * @param img
71 * the {@link Image}
72 *
73 * @return the {@link Image} object
74 *
75 * @throws IOException
76 * in case of IO error
77 */
78 public static BufferedImage fromImage(Image img) throws IOException {
79 InputStream in = img.newInputStream();
80 BufferedImage image;
81 try {
82 int orientation;
83 try {
84 orientation = getExifTransorm(in);
85 } catch (Exception e) {
86 // no EXIF transform, ok
87 orientation = -1;
88 }
89
90 in.reset();
91
92 try {
93 image = ImageIO.read(in);
94 } catch (IllegalArgumentException e) {
95 throw e;
96 } catch (Exception e) {
97 throw new IOException("Undocumented exception occured, "
98 + "converting to IOException", e);
99 }
100
101 if (image == null) {
102 throw new IOException("Failed to convert input to image");
103 }
104
105 // Note: this code has been found on Internet;
106 // thank you anonymous coder.
107 int width = image.getWidth();
108 int height = image.getHeight();
109 AffineTransform affineTransform = new AffineTransform();
110
111 switch (orientation) {
112 case 1:
113 affineTransform = null;
114 break;
115 case 2: // Flip X
116 affineTransform.scale(-1.0, 1.0);
117 affineTransform.translate(-width, 0);
118 break;
119 case 3: // PI rotation
120 affineTransform.translate(width, height);
121 affineTransform.rotate(Math.PI);
122 break;
123 case 4: // Flip Y
124 affineTransform.scale(1.0, -1.0);
125 affineTransform.translate(0, -height);
126 break;
127 case 5: // - PI/2 and Flip X
128 affineTransform.rotate(-Math.PI / 2);
129 affineTransform.scale(-1.0, 1.0);
130 break;
131 case 6: // -PI/2 and -width
132 affineTransform.translate(height, 0);
133 affineTransform.rotate(Math.PI / 2);
134 break;
135 case 7: // PI/2 and Flip
136 affineTransform.scale(-1.0, 1.0);
137 affineTransform.translate(-height, 0);
138 affineTransform.translate(0, width);
139 affineTransform.rotate(3 * Math.PI / 2);
140 break;
141 case 8: // PI / 2
142 affineTransform.translate(0, width);
143 affineTransform.rotate(3 * Math.PI / 2);
144 break;
145 default:
146 affineTransform = null;
147 break;
148 }
149
150 if (affineTransform != null) {
151 AffineTransformOp affineTransformOp = new AffineTransformOp(
152 affineTransform, AffineTransformOp.TYPE_BILINEAR);
153
154 BufferedImage transformedImage = new BufferedImage(width,
155 height, image.getType());
156 transformedImage = affineTransformOp.filter(image,
157 transformedImage);
158
159 image = transformedImage;
160 }
161 //
162 } finally {
163 in.close();
164 }
165
166 return image;
167 }
168 }