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
)
49 * the actual image width
51 * the actual image height
53 * the base width of the target dimension for snap sizes
55 * the base height of the target dimension for snap sizes
57 * the zoom factor (ignored on snap mode)
59 * NULL for no snap mode, TRUE to snap to width and FALSE for
62 * @return the scaled size, width is [0] and height is [1] (minimum is 1x1)
64 protected static Integer
[] scaleSize(int imageWidth
, int imageHeight
,
65 int areaWidth
, int areaHeight
, double zoom
, Boolean snapMode
) {
68 if (snapMode
== null) {
69 width
= (int) Math
.round(imageWidth
* zoom
);
70 height
= (int) Math
.round(imageHeight
* zoom
);
71 } else if (snapMode
) {
74 .round((((double) areaWidth
) / imageWidth
) * imageHeight
);
78 .round((((double) areaHeight
) / imageHeight
) * imageWidth
);
87 return new Integer
[] { width
, height
};
91 * Return the EXIF transformation flag of this image if any.
94 * Note: this code has been found on internet; thank you anonymous coder.
98 * the data {@link InputStream}
100 * @return the transformation flag if any
102 * @throws IOException
103 * in case of IO error
105 protected static int getExifTransorm(InputStream in
) throws IOException
{
106 int[] exif_data
= new int[100];
110 /* Read File head, check for JPEG SOI + Exif APP1 */
111 for (int i
= 0; i
< 4; i
++)
112 exif_data
[i
] = in
.read();
114 if (exif_data
[0] != 0xFF || exif_data
[1] != 0xD8
115 || exif_data
[2] != 0xFF || exif_data
[3] != 0xE1)
118 /* Get the marker parameter length count */
119 int length
= (in
.read() << 8 | in
.read());
121 /* Length includes itself, so must be at least 2 */
122 /* Following Exif data length must be at least 6 */
126 /* Read Exif head, check for "Exif" */
127 for (int i
= 0; i
< 6; i
++)
128 exif_data
[i
] = in
.read();
130 if (exif_data
[0] != 0x45 || exif_data
[1] != 0x78
131 || exif_data
[2] != 0x69 || exif_data
[3] != 0x66
132 || exif_data
[4] != 0 || exif_data
[5] != 0)
136 length
= length
> exif_data
.length ? exif_data
.length
: length
;
137 for (int i
= 0; i
< length
; i
++)
138 exif_data
[i
] = in
.read();
141 return -1; /* Length of an IFD entry */
143 /* Discover byte order */
144 if (exif_data
[0] == 0x49 && exif_data
[1] == 0x49)
146 else if (exif_data
[0] == 0x4D && exif_data
[1] == 0x4D)
152 if (is_motorola
== 1) {
153 if (exif_data
[2] != 0)
155 if (exif_data
[3] != 0x2A)
158 if (exif_data
[3] != 0)
160 if (exif_data
[2] != 0x2A)
164 /* Get first IFD offset (offset to IFD0) */
166 if (is_motorola
== 1) {
167 if (exif_data
[4] != 0)
169 if (exif_data
[5] != 0)
171 offset
= exif_data
[6];
173 offset
+= exif_data
[7];
175 if (exif_data
[7] != 0)
177 if (exif_data
[6] != 0)
179 offset
= exif_data
[5];
181 offset
+= exif_data
[4];
183 if (offset
> length
- 2)
184 return -1; /* check end of data segment */
186 /* Get the number of directory entries contained in this IFD */
188 if (is_motorola
== 1) {
189 number_of_tags
= exif_data
[offset
];
190 number_of_tags
<<= 8;
191 number_of_tags
+= exif_data
[offset
+ 1];
193 number_of_tags
= exif_data
[offset
+ 1];
194 number_of_tags
<<= 8;
195 number_of_tags
+= exif_data
[offset
];
197 if (number_of_tags
== 0)
201 /* Search for Orientation Tag in IFD0 */
203 if (offset
> length
- 12)
204 return -1; /* check end of data segment */
207 if (is_motorola
== 1) {
208 tagnum
= exif_data
[offset
];
210 tagnum
+= exif_data
[offset
+ 1];
212 tagnum
= exif_data
[offset
+ 1];
214 tagnum
+= exif_data
[offset
];
216 if (tagnum
== 0x0112)
217 break; /* found Orientation Tag */
218 if (--number_of_tags
== 0)
223 /* Get the Orientation value */
224 if (is_motorola
== 1) {
225 if (exif_data
[offset
+ 8] != 0)
227 set_flag
= exif_data
[offset
+ 9];
229 if (exif_data
[offset
+ 9] != 0)
231 set_flag
= exif_data
[offset
+ 8];
240 * Check that the class can operate (for instance, that all the required
241 * libraries or frameworks are present).
243 * @return TRUE if it works
245 abstract protected boolean check();
248 * Create a new {@link ImageUtils}.
250 * @return the {@link ImageUtils}
252 private static ImageUtils
newObject() {
253 for (String clazz
: new String
[] { "be.nikiroo.utils.ui.ImageUtilsAwt",
254 "be.nikiroo.utils.android.ImageUtilsAndroid" }) {
256 ImageUtils obj
= (ImageUtils
) SerialUtils
.createObject(clazz
);
260 } catch (Throwable e
) {