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° */
42 protected boolean check() {
43 // Will not work if ImageIO is not available
44 ImageIO
.getCacheDirectory();
49 public void saveAsImage(Image img
, File target
, String format
)
52 BufferedImage image
= fromImage(img
);
57 ok
= ImageIO
.write(image
, format
, target
);
58 } catch (IOException e
) {
62 // Some formats are not reliable
64 if (!ok
&& !format
.equals("png")) {
66 ok
= ImageIO
.write(image
, "png", target
);
67 } catch (IllegalArgumentException e
) {
69 } catch (Exception e
) {
70 throw new IOException("Undocumented exception occured, "
71 + "converting to IOException", e
);
76 throw new IOException(
77 "Cannot find a writer for this image and format: "
80 } catch (IOException e
) {
81 throw new IOException("Cannot write image to " + target
, e
);
86 * Convert the given {@link Image} into a {@link BufferedImage} object,
87 * respecting the EXIF transformations if any.
92 * @return the {@link Image} object
97 public static BufferedImage
fromImage(Image img
) throws IOException
{
98 return fromImage(img
, Rotation
.NONE
);
102 * Convert the given {@link Image} into a {@link BufferedImage} object,
103 * respecting the EXIF transformations if any.
108 * the rotation to apply, if any (can be null, same as
109 * {@link Rotation#NONE})
111 * @return the {@link Image} object
113 * @throws IOException
114 * in case of IO error
116 public static BufferedImage
fromImage(Image img
, Rotation rotation
)
118 InputStream in
= img
.newInputStream();
123 orientation
= getExifTransorm(in
);
124 } catch (Exception e
) {
125 // no EXIF transform, ok
132 image
= ImageIO
.read(in
);
133 } catch (IllegalArgumentException e
) {
135 } catch (Exception e
) {
136 throw new IOException("Undocumented exception occured, "
137 + "converting to IOException", e
);
142 if (img
.getSize() <= 2048) {
145 InputStream inData
= img
.newInputStream();
147 data
= IOUtils
.toByteArray(inData
);
151 extra
= ", content: " + new String(data
, "UTF-8");
152 } catch (Exception e
) {
153 extra
= ", content unavailable";
156 String ssize
= StringUtils
.formatNumber(img
.getSize());
157 throw new IOException(
158 "Failed to convert input to image, size was: " + ssize
162 // Note: this code has been found on Internet;
163 // thank you anonymous coder.
164 int width
= image
.getWidth();
165 int height
= image
.getHeight();
166 AffineTransform affineTransform
= new AffineTransform();
168 switch (orientation
) {
170 affineTransform
= null;
173 affineTransform
.scale(-1.0, 1.0);
174 affineTransform
.translate(-width
, 0);
176 case 3: // PI rotation
177 affineTransform
.translate(width
, height
);
178 affineTransform
.rotate(Math
.PI
);
181 affineTransform
.scale(1.0, -1.0);
182 affineTransform
.translate(0, -height
);
184 case 5: // - PI/2 and Flip X
185 affineTransform
.rotate(-Math
.PI
/ 2);
186 affineTransform
.scale(-1.0, 1.0);
188 case 6: // -PI/2 and -width
189 affineTransform
.translate(height
, 0);
190 affineTransform
.rotate(Math
.PI
/ 2);
192 case 7: // PI/2 and Flip
193 affineTransform
.scale(-1.0, 1.0);
194 affineTransform
.translate(-height
, 0);
195 affineTransform
.translate(0, width
);
196 affineTransform
.rotate(3 * Math
.PI
/ 2);
199 affineTransform
.translate(0, width
);
200 affineTransform
.rotate(3 * Math
.PI
/ 2);
203 affineTransform
= null;
207 if (rotation
== null)
208 rotation
= Rotation
.NONE
;
212 if (affineTransform
== null) {
213 affineTransform
= new AffineTransform();
215 affineTransform
.translate(height
, 0);
216 affineTransform
.rotate(Math
.PI
/ 2);
224 if (affineTransform
== null) {
225 affineTransform
= new AffineTransform();
227 affineTransform
.translate(0, width
);
228 affineTransform
.rotate(3 * Math
.PI
/ 2);
236 if (affineTransform
== null) {
237 affineTransform
= new AffineTransform();
239 affineTransform
.translate(width
, height
);
240 affineTransform
.rotate(Math
.PI
);
246 if (affineTransform
!= null) {
247 AffineTransformOp affineTransformOp
= new AffineTransformOp(
248 affineTransform
, AffineTransformOp
.TYPE_BILINEAR
);
250 BufferedImage transformedImage
= new BufferedImage(width
,
251 height
, image
.getType());
252 transformedImage
= affineTransformOp
.filter(image
,
255 image
= transformedImage
;
269 * the actual image size
271 * the base size of the target to get snap sizes for
273 * the zoom factor (ignored on snap mode)
275 * NULL for no snap mode, TRUE to snap to width and FALSE for
278 * @return the scaled (minimum is 1x1)
280 public static Dimension
scaleSize(Dimension imageSize
, Dimension areaSize
,
281 double zoom
, Boolean snapMode
) {
282 Integer
[] sz
= scaleSize(imageSize
.width
, imageSize
.height
,
283 areaSize
.width
, areaSize
.height
, zoom
, snapMode
);
284 return new Dimension(sz
[0], sz
[1]);
288 * Resize the given image.
291 * the image to resize
293 * the base size of the target dimension for snap sizes
295 * the zoom factor (ignored on snap mode)
297 * NULL for no snap mode, TRUE to snap to width and FALSE for
300 * @return a new, resized image
302 public static BufferedImage
scaleImage(BufferedImage image
,
303 Dimension areaSize
, double zoom
, Boolean snapMode
) {
304 Dimension scaledSize
= scaleSize(
305 new Dimension(image
.getWidth(), image
.getHeight()), areaSize
,
308 return scaleImage(image
, scaledSize
);
312 * Resize the given image.
315 * the image to resize
319 * @return a new, resized image
321 public static BufferedImage
scaleImage(BufferedImage image
,
322 Dimension targetSize
) {
323 BufferedImage resizedImage
= new BufferedImage(targetSize
.width
,
324 targetSize
.height
, BufferedImage
.TYPE_4BYTE_ABGR
);
325 Graphics2D g
= resizedImage
.createGraphics();
327 g
.drawImage(image
, 0, 0, targetSize
.width
, targetSize
.height
, null);