1 package be
.nikiroo
.utils
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
7 import be
.nikiroo
.utils
.serial
.SerialUtils
;
10 * This class offer some utilities based around images.
14 public abstract class ImageUtils
{
15 private static ImageUtils instance
= newObject();
18 * Get a (unique) instance of an {@link ImageUtils} compatible with your
21 * @return an {@link ImageUtils}
23 public static ImageUtils
getInstance() {
28 * Save the given resource as an image on disk using the given image format
29 * for content, or with "png" format if it fails.
36 * the file format ("png", "jpeg", "bmp"...)
39 * in case of I/O error
41 public abstract void saveAsImage(Image img
, File target
, String format
)
48 * the base width of the target dimension for snap sizes
50 * the base height of the target dimension for snap sizes
52 * the actual image width
54 * the actual image height
56 * the zoom factor, or -1 for snap size
57 * @param zoomSnapWidth
58 * if snap size, TRUE to snap to width (and FALSE, snap to
61 * @return the scaled size, width is [0] and height is [1] (minimum is 1x1)
63 protected static Integer
[] scaleSize(int areaWidth
, int areaHeight
,
64 int imageWidth
, int imageHeight
, double zoom
, boolean zoomSnapWidth
) {
68 width
= (int) Math
.round(imageWidth
* zoom
);
69 height
= (int) Math
.round(imageHeight
* zoom
);
73 height
= (int) Math
.round(
74 (((double) areaWidth
) / imageWidth
) * imageHeight
);
77 width
= (int) Math
.round(
78 (((double) areaHeight
) / imageHeight
) * imageWidth
);
88 return new Integer
[] { width
, height
};
92 * Return the EXIF transformation flag of this image if any.
95 * Note: this code has been found on internet; thank you anonymous coder.
99 * the data {@link InputStream}
101 * @return the transformation flag if any
103 * @throws IOException
104 * in case of IO error
106 protected static int getExifTransorm(InputStream in
) throws IOException
{
107 int[] exif_data
= new int[100];
111 /* Read File head, check for JPEG SOI + Exif APP1 */
112 for (int i
= 0; i
< 4; i
++)
113 exif_data
[i
] = in
.read();
115 if (exif_data
[0] != 0xFF || exif_data
[1] != 0xD8
116 || exif_data
[2] != 0xFF || exif_data
[3] != 0xE1)
119 /* Get the marker parameter length count */
120 int length
= (in
.read() << 8 | in
.read());
122 /* Length includes itself, so must be at least 2 */
123 /* Following Exif data length must be at least 6 */
127 /* Read Exif head, check for "Exif" */
128 for (int i
= 0; i
< 6; i
++)
129 exif_data
[i
] = in
.read();
131 if (exif_data
[0] != 0x45 || exif_data
[1] != 0x78
132 || exif_data
[2] != 0x69 || exif_data
[3] != 0x66
133 || exif_data
[4] != 0 || exif_data
[5] != 0)
137 length
= length
> exif_data
.length ? exif_data
.length
: length
;
138 for (int i
= 0; i
< length
; i
++)
139 exif_data
[i
] = in
.read();
142 return -1; /* Length of an IFD entry */
144 /* Discover byte order */
145 if (exif_data
[0] == 0x49 && exif_data
[1] == 0x49)
147 else if (exif_data
[0] == 0x4D && exif_data
[1] == 0x4D)
153 if (is_motorola
== 1) {
154 if (exif_data
[2] != 0)
156 if (exif_data
[3] != 0x2A)
159 if (exif_data
[3] != 0)
161 if (exif_data
[2] != 0x2A)
165 /* Get first IFD offset (offset to IFD0) */
167 if (is_motorola
== 1) {
168 if (exif_data
[4] != 0)
170 if (exif_data
[5] != 0)
172 offset
= exif_data
[6];
174 offset
+= exif_data
[7];
176 if (exif_data
[7] != 0)
178 if (exif_data
[6] != 0)
180 offset
= exif_data
[5];
182 offset
+= exif_data
[4];
184 if (offset
> length
- 2)
185 return -1; /* check end of data segment */
187 /* Get the number of directory entries contained in this IFD */
189 if (is_motorola
== 1) {
190 number_of_tags
= exif_data
[offset
];
191 number_of_tags
<<= 8;
192 number_of_tags
+= exif_data
[offset
+ 1];
194 number_of_tags
= exif_data
[offset
+ 1];
195 number_of_tags
<<= 8;
196 number_of_tags
+= exif_data
[offset
];
198 if (number_of_tags
== 0)
202 /* Search for Orientation Tag in IFD0 */
204 if (offset
> length
- 12)
205 return -1; /* check end of data segment */
208 if (is_motorola
== 1) {
209 tagnum
= exif_data
[offset
];
211 tagnum
+= exif_data
[offset
+ 1];
213 tagnum
= exif_data
[offset
+ 1];
215 tagnum
+= exif_data
[offset
];
217 if (tagnum
== 0x0112)
218 break; /* found Orientation Tag */
219 if (--number_of_tags
== 0)
224 /* Get the Orientation value */
225 if (is_motorola
== 1) {
226 if (exif_data
[offset
+ 8] != 0)
228 set_flag
= exif_data
[offset
+ 9];
230 if (exif_data
[offset
+ 9] != 0)
232 set_flag
= exif_data
[offset
+ 8];
241 * Check that the class can operate (for instance, that all the required
242 * libraries or frameworks are present).
244 * @return TRUE if it works
246 abstract protected boolean check();
249 * Create a new {@link ImageUtils}.
251 * @return the {@link ImageUtils}
253 private static ImageUtils
newObject() {
254 for (String clazz
: new String
[] { "be.nikiroo.utils.ui.ImageUtilsAwt",
255 "be.nikiroo.utils.android.ImageUtilsAndroid" }) {
257 ImageUtils obj
= (ImageUtils
) SerialUtils
.createObject(clazz
);
261 } catch (Throwable e
) {