1 package be
.nikiroo
.utils
.ui
;
3 import java
.awt
.Dimension
;
4 import java
.awt
.Graphics2D
;
5 import java
.awt
.geom
.AffineTransform
;
6 import java
.awt
.image
.AffineTransformOp
;
7 import java
.awt
.image
.BufferedImage
;
9 import java
.io
.IOException
;
10 import java
.io
.InputStream
;
12 import javax
.imageio
.ImageIO
;
14 import be
.nikiroo
.utils
.IOUtils
;
15 import be
.nikiroo
.utils
.Image
;
16 import be
.nikiroo
.utils
.ImageUtils
;
17 import be
.nikiroo
.utils
.StringUtils
;
20 * This class offer some utilities based around images and uses java.awt.
24 public class ImageUtilsAwt
extends ImageUtils
{
26 * A rotation to perform on an image.
30 public enum Rotation
{
33 /** Rotate the image to the right */
35 /** Rotate the image to the left */
37 /** Rotate the image by 180° */
41 protected boolean check() {
42 // Will not work if ImageIO is not available
43 ImageIO
.getCacheDirectory();
48 public void saveAsImage(Image img
, File target
, String format
)
51 BufferedImage image
= fromImage(img
);
56 ok
= ImageIO
.write(image
, format
, target
);
57 } catch (IOException e
) {
61 // Some formats are not reliable
63 if (!ok
&& !format
.equals("png")) {
65 ok
= ImageIO
.write(image
, "png", target
);
66 } catch (IllegalArgumentException e
) {
68 } catch (Exception e
) {
69 throw new IOException("Undocumented exception occured, "
70 + "converting to IOException", e
);
75 throw new IOException(
76 "Cannot find a writer for this image and format: "
79 } catch (IOException e
) {
80 throw new IOException("Cannot write image to " + target
, e
);
85 * Convert the given {@link Image} into a {@link BufferedImage} object,
86 * respecting the EXIF transformations if any.
91 * @return the {@link Image} object
96 public static BufferedImage
fromImage(Image img
) throws IOException
{
97 return fromImage(img
, Rotation
.NONE
);
101 * Convert the given {@link Image} into a {@link BufferedImage} object,
102 * respecting the EXIF transformations if any.
107 * the rotation to apply, if any (can be null, same as
108 * {@link Rotation#NONE})
110 * @return the {@link Image} object
112 * @throws IOException
113 * in case of IO error
115 public static BufferedImage
fromImage(Image img
, Rotation rotation
) throws IOException
{
116 InputStream in
= img
.newInputStream();
121 orientation
= getExifTransorm(in
);
122 } catch (Exception e
) {
123 // no EXIF transform, ok
130 image
= ImageIO
.read(in
);
131 } catch (IllegalArgumentException e
) {
133 } catch (Exception e
) {
134 throw new IOException("Undocumented exception occured, "
135 + "converting to IOException", e
);
140 if (img
.getSize() <= 2048) {
143 InputStream inData
= img
.newInputStream();
145 data
= IOUtils
.toByteArray(inData
);
149 extra
= ", content: "
150 + new String(data
, "UTF-8");
151 } catch (Exception e
) {
152 extra
= ", content unavailable";
155 String ssize
= StringUtils
.formatNumber(img
.getSize());
156 throw new IOException(
157 "Failed to convert input to image, size was: " + ssize
161 // Note: this code has been found on Internet;
162 // thank you anonymous coder.
163 int width
= image
.getWidth();
164 int height
= image
.getHeight();
165 AffineTransform affineTransform
= new AffineTransform();
167 switch (orientation
) {
169 affineTransform
= null;
172 affineTransform
.scale(-1.0, 1.0);
173 affineTransform
.translate(-width
, 0);
175 case 3: // PI rotation
176 affineTransform
.translate(width
, height
);
177 affineTransform
.rotate(Math
.PI
);
180 affineTransform
.scale(1.0, -1.0);
181 affineTransform
.translate(0, -height
);
183 case 5: // - PI/2 and Flip X
184 affineTransform
.rotate(-Math
.PI
/ 2);
185 affineTransform
.scale(-1.0, 1.0);
187 case 6: // -PI/2 and -width
188 affineTransform
.translate(height
, 0);
189 affineTransform
.rotate(Math
.PI
/ 2);
191 case 7: // PI/2 and Flip
192 affineTransform
.scale(-1.0, 1.0);
193 affineTransform
.translate(-height
, 0);
194 affineTransform
.translate(0, width
);
195 affineTransform
.rotate(3 * Math
.PI
/ 2);
198 affineTransform
.translate(0, width
);
199 affineTransform
.rotate(3 * Math
.PI
/ 2);
202 affineTransform
= null;
206 if (rotation
== null)
207 rotation
= Rotation
.NONE
;
211 if (affineTransform
== null) {
212 affineTransform
= new AffineTransform();
214 affineTransform
.translate(height
, 0);
215 affineTransform
.rotate(Math
.PI
/ 2);
218 if (affineTransform
== null) {
219 affineTransform
= new AffineTransform();
221 affineTransform
.translate(0, width
);
222 affineTransform
.rotate(3 * Math
.PI
/ 2);
225 if (affineTransform
== null) {
226 affineTransform
= new AffineTransform();
228 affineTransform
.translate(width
, height
);
229 affineTransform
.rotate(Math
.PI
);
235 if (affineTransform
!= null) {
236 AffineTransformOp affineTransformOp
= new AffineTransformOp(
237 affineTransform
, AffineTransformOp
.TYPE_BILINEAR
);
239 BufferedImage transformedImage
= new BufferedImage(width
,
240 height
, image
.getType());
241 transformedImage
= affineTransformOp
.filter(image
,
244 image
= transformedImage
;
255 * Resize the given image.
258 * the base size of the target dimension for snap sizes
260 * the image to resize
262 * the zoom factor or -1 for snap size
263 * @param zoomSnapWidth
264 * if snap size, TRUE to snap to width (and FALSE, snap to
267 * @return a new, resized image
269 public static BufferedImage
scaleImage(Dimension areaSize
,
270 BufferedImage image
, double zoom
, boolean zoomSnapWidth
) {
271 Integer scaledSize
[] = scaleSize(areaSize
.width
, areaSize
.height
,
272 image
.getWidth(), image
.getHeight(), zoom
, zoomSnapWidth
);
273 int width
= scaledSize
[0];
274 int height
= scaledSize
[1];
275 BufferedImage resizedImage
= new BufferedImage(width
, height
,
276 BufferedImage
.TYPE_4BYTE_ABGR
);
277 Graphics2D g
= resizedImage
.createGraphics();
279 g
.drawImage(image
, 0, 0, width
, height
, null);