Image: perfs improvement
[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 public void saveAsImage(Image img, File target, String format)
23 throws IOException {
24 try {
25 BufferedImage image = fromImage(img);
26
27 boolean ok = false;
28 try {
29
30 ok = ImageIO.write(image, format, target);
31 } catch (IOException e) {
32 ok = false;
33 }
34
35 // Some formats are not reliable
36 // Second chance: PNG
37 if (!ok && !format.equals("png")) {
38 try {
39 ok = ImageIO.write(image, "png", target);
40 } catch (IllegalArgumentException e) {
41 throw e;
42 } catch (Exception e) {
43 throw new IOException("Undocumented exception occured, "
44 + "converting to IOException", e);
45 }
46 }
47
48 if (!ok) {
49 throw new IOException(
50 "Cannot find a writer for this image and format: "
51 + format);
52 }
53 } catch (IOException e) {
54 throw new IOException("Cannot write image to " + target, e);
55 }
56 }
57
58 /**
59 * Convert the given {@link Image} into a {@link BufferedImage} object,
60 * respecting the EXIF transformations if any.
61 *
62 * @param img
63 * the {@link Image}
64 *
65 * @return the {@link Image} object
66 *
67 * @throws IOException
68 * in case of IO error
69 */
70 public static BufferedImage fromImage(Image img) throws IOException {
71 InputStream in = img.newInputStream();
72 BufferedImage image;
73 try {
74 int orientation;
75 try {
76 orientation = getExifTransorm(in);
77 } catch (Exception e) {
78 // no EXIF transform, ok
79 orientation = -1;
80 }
81
82 in.reset();
83
84 try {
85 image = ImageIO.read(in);
86 } catch (IllegalArgumentException e) {
87 throw e;
88 } catch (Exception e) {
89 throw new IOException("Undocumented exception occured, "
90 + "converting to IOException", e);
91 }
92
93 if (image == null) {
94 throw new IOException("Failed to convert input to image");
95 }
96
97 // Note: this code has been found on Internet;
98 // thank you anonymous coder.
99 int width = image.getWidth();
100 int height = image.getHeight();
101 AffineTransform affineTransform = new AffineTransform();
102
103 switch (orientation) {
104 case 1:
105 affineTransform = null;
106 break;
107 case 2: // Flip X
108 affineTransform.scale(-1.0, 1.0);
109 affineTransform.translate(-width, 0);
110 break;
111 case 3: // PI rotation
112 affineTransform.translate(width, height);
113 affineTransform.rotate(Math.PI);
114 break;
115 case 4: // Flip Y
116 affineTransform.scale(1.0, -1.0);
117 affineTransform.translate(0, -height);
118 break;
119 case 5: // - PI/2 and Flip X
120 affineTransform.rotate(-Math.PI / 2);
121 affineTransform.scale(-1.0, 1.0);
122 break;
123 case 6: // -PI/2 and -width
124 affineTransform.translate(height, 0);
125 affineTransform.rotate(Math.PI / 2);
126 break;
127 case 7: // PI/2 and Flip
128 affineTransform.scale(-1.0, 1.0);
129 affineTransform.translate(-height, 0);
130 affineTransform.translate(0, width);
131 affineTransform.rotate(3 * Math.PI / 2);
132 break;
133 case 8: // PI / 2
134 affineTransform.translate(0, width);
135 affineTransform.rotate(3 * Math.PI / 2);
136 break;
137 default:
138 affineTransform = null;
139 break;
140 }
141
142 if (affineTransform != null) {
143 AffineTransformOp affineTransformOp = new AffineTransformOp(
144 affineTransform, AffineTransformOp.TYPE_BILINEAR);
145
146 BufferedImage transformedImage = new BufferedImage(width,
147 height, image.getType());
148 transformedImage = affineTransformOp.filter(image,
149 transformedImage);
150
151 image = transformedImage;
152 }
153 //
154 } finally {
155 in.close();
156 }
157
158 return image;
159 }
160 }