Commit | Line | Data |
---|---|---|
80500544 NR |
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 { | |
e8aa5bf9 | 26 | BufferedImage image = fromImage(img); |
80500544 NR |
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 | |
e8aa5bf9 | 37 | // Second chance: PNG |
80500544 NR |
38 | if (!ok && !format.equals("png")) { |
39 | ok = ImageIO.write(image, "png", target); | |
40 | } | |
41 | ||
42 | if (!ok) { | |
43 | throw new IOException( | |
44 | "Cannot find a writer for this image and format: " | |
45 | + format); | |
46 | } | |
47 | } catch (IOException e) { | |
48 | throw new IOException("Cannot write image to " + target, e); | |
49 | } | |
50 | } | |
51 | ||
52 | /** | |
53 | * Convert the given {@link Image} into a {@link BufferedImage} object, | |
54 | * respecting the EXIF transformations if any. | |
55 | * | |
56 | * @param img | |
57 | * the {@link Image} | |
58 | * | |
59 | * @return the {@link Image} object | |
60 | * | |
61 | * @throws IOException | |
62 | * in case of IO error | |
63 | */ | |
e704a414 | 64 | public static BufferedImage fromImage(Image img) throws IOException { |
80500544 NR |
65 | InputStream in = new ByteArrayInputStream(img.getData()); |
66 | ||
67 | int orientation; | |
68 | try { | |
69 | orientation = getExifTransorm(in); | |
70 | } catch (Exception e) { | |
71 | // no EXIF transform, ok | |
72 | orientation = -1; | |
73 | } | |
74 | ||
75 | in.reset(); | |
76 | BufferedImage image = ImageIO.read(in); | |
77 | ||
78 | if (image == null) { | |
79 | throw new IOException("Failed to convert input to image"); | |
80 | } | |
81 | ||
82 | // Note: this code has been found on Internet; | |
83 | // thank you anonymous coder. | |
84 | int width = image.getWidth(); | |
85 | int height = image.getHeight(); | |
86 | AffineTransform affineTransform = new AffineTransform(); | |
87 | ||
88 | switch (orientation) { | |
89 | case 1: | |
90 | affineTransform = null; | |
91 | break; | |
92 | case 2: // Flip X | |
93 | affineTransform.scale(-1.0, 1.0); | |
94 | affineTransform.translate(-width, 0); | |
95 | break; | |
96 | case 3: // PI rotation | |
97 | affineTransform.translate(width, height); | |
98 | affineTransform.rotate(Math.PI); | |
99 | break; | |
100 | case 4: // Flip Y | |
101 | affineTransform.scale(1.0, -1.0); | |
102 | affineTransform.translate(0, -height); | |
103 | break; | |
104 | case 5: // - PI/2 and Flip X | |
105 | affineTransform.rotate(-Math.PI / 2); | |
106 | affineTransform.scale(-1.0, 1.0); | |
107 | break; | |
108 | case 6: // -PI/2 and -width | |
109 | affineTransform.translate(height, 0); | |
110 | affineTransform.rotate(Math.PI / 2); | |
111 | break; | |
112 | case 7: // PI/2 and Flip | |
113 | affineTransform.scale(-1.0, 1.0); | |
114 | affineTransform.translate(-height, 0); | |
115 | affineTransform.translate(0, width); | |
116 | affineTransform.rotate(3 * Math.PI / 2); | |
117 | break; | |
118 | case 8: // PI / 2 | |
119 | affineTransform.translate(0, width); | |
120 | affineTransform.rotate(3 * Math.PI / 2); | |
121 | break; | |
122 | default: | |
123 | affineTransform = null; | |
124 | break; | |
125 | } | |
126 | ||
127 | if (affineTransform != null) { | |
128 | AffineTransformOp affineTransformOp = new AffineTransformOp( | |
129 | affineTransform, AffineTransformOp.TYPE_BILINEAR); | |
130 | ||
131 | BufferedImage transformedImage = new BufferedImage(width, height, | |
132 | image.getType()); | |
133 | transformedImage = affineTransformOp | |
134 | .filter(image, transformedImage); | |
135 | ||
136 | image = transformedImage; | |
137 | } | |
138 | // | |
139 | ||
140 | return image; | |
141 | } | |
142 | } |