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