Version 4.4.1
[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;
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, height,
147 image.getType());
148 transformedImage = affineTransformOp
149 .filter(image, transformedImage);
150
151 image = transformedImage;
152 }
153 //
154
155 return image;
156 }
157 }