1 package be
.nikiroo
.utils
;
3 import java
.io
.ByteArrayInputStream
;
4 import java
.io
.Closeable
;
6 import java
.io
.FileInputStream
;
7 import java
.io
.IOException
;
8 import java
.io
.InputStream
;
10 import be
.nikiroo
.utils
.streams
.MarkableFileInputStream
;
13 * This class represents an image data.
17 public class Image
implements Closeable
{
18 static private File tempRoot
;
19 static private TempFiles tmpRepository
;
20 static private long count
= 0;
21 static private Object lock
= new Object();
26 * Do not use -- for serialisation purposes only.
28 @SuppressWarnings("unused")
33 * Create a new {@link Image} with the given data.
38 public Image(byte[] data
) {
39 ByteArrayInputStream in
= new ByteArrayInputStream(data
);
41 this.data
= getTemporaryFile();
42 IOUtils
.write(in
, this.data
);
43 } catch (IOException e
) {
44 throw new RuntimeException(e
);
48 } catch (IOException e
) {
49 throw new RuntimeException(e
);
55 * Create a new {@link Image} from its Base64 representation.
58 * the {@link Image} in Base64 format
61 * in case of I/O error
63 public Image(String base64
) throws IOException
{
64 this(Base64
.decode(base64
));
68 * Create a new {@link Image} from a stream.
74 * in case of I/O error
76 public Image(InputStream in
) throws IOException
{
77 data
= getTemporaryFile();
78 IOUtils
.write(in
, data
);
82 * Generate an {@link InputStream} for this {@link Image}.
84 * This {@link InputStream} will (always) be a new one, and <b>you</b> are
87 * Note: take care that the {@link InputStream} <b>must not</b> live past
88 * the {@link Image} life time!
93 * in case of I/O error
95 public InputStream
newInputStream() throws IOException
{
96 return new MarkableFileInputStream(new FileInputStream(data
));
100 * <b>Read</b> the actual image data, as a byte array.
102 * Note: if possible, prefer the {@link Image#newInputStream()} method, as
103 * it can be more efficient.
105 * @return the image data
107 public byte[] getData() {
109 InputStream in
= newInputStream();
111 return IOUtils
.toByteArray(in
);
115 } catch (IOException e
) {
116 throw new RuntimeException(e
);
121 * Convert the given {@link Image} object into a Base64 representation of
122 * the same {@link Image} object.
124 * Note: if possible, prefer the {@link Image#newInputStream()} method, as
125 * it can be more efficient.
127 * @return the Base64 representation
129 public String
toBase64() {
131 return StringUtils
.base64(getData(), false);
132 } catch (IOException e
) {
133 throw new RuntimeException(e
);
138 * Closing the {@link Image} will delete the associated temporary file on
141 * Note that even if you don't, the program will still <b>try</b> to delete
142 * all the temporary files at JVM termination.
145 public void close() throws IOException
{
147 synchronized (lock
) {
151 tmpRepository
.close();
152 tmpRepository
= null;
158 protected void finalize() throws Throwable
{
167 * Return a newly created temporary file to work on.
171 * @throws IOException
172 * in case of I/O error
174 private File
getTemporaryFile() throws IOException
{
175 synchronized (lock
) {
176 if (tmpRepository
== null) {
177 tmpRepository
= new TempFiles(tempRoot
, "images");
183 return tmpRepository
.createTempFile("image");
188 * Change the temporary root directory used by the program.
190 * Caution: the directory will be <b>owned</b> by the system, all its files
191 * now belong to us (and will most probably be deleted).
193 * Note: it may take some time until the new temporary root is used, we
194 * first need to make sure the previous one is not used anymore (i.e., we
195 * must reach a point where no unclosed {@link Image} remains in memory) to
196 * switch the temporary root.
199 * the new temporary root, which will be <b>owned</b> by the
202 public static void setTemporaryFilesRoot(File root
) {