1 package de.desy.acop.video.timageio;
2
3 import java.awt.image.BufferedImage;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.net.URL;
8 import java.util.Iterator;
9
10 import javax.imageio.IIOException;
11 import javax.imageio.IIOImage;
12 import javax.imageio.ImageIO;
13 import javax.imageio.ImageReadParam;
14 import javax.imageio.ImageReader;
15 import javax.imageio.ImageTypeSpecifier;
16 import javax.imageio.ImageWriter;
17 import javax.imageio.metadata.IIOMetadata;
18 import javax.imageio.stream.ImageInputStream;
19 import javax.imageio.stream.ImageOutputStream;
20
21 /**
22 * A class containing static convenience methods for performing simple encoding
23 * and decoding of Tine image.
24 *
25 * @author David Melkumyan, DESY Zeuthen
26 * @since October 2009
27 */
28 public final class TImageIO {
29
30 /**
31 * Constructor is private to prevent instantiation.
32 */
33 private TImageIO() {
34 }
35
36 /**
37 * Returns a <code>TBufferedImage</code> as the result of decoding a
38 * supplied <code>File</code><br>
39 * with an <code>ImageReader</code> chosen automatically from among those
40 * currently registered.
41 *
42 * <p>
43 * Note that there is no <code>read</code> method that takes a filename as a
44 * <code>String</code>;<br>
45 * use this method instead after creating a <code>File</code> from the
46 * filename.
47 *
48 * @param input
49 * a <code>File</code> to read from.
50 *
51 * @return a <code>TBufferedImage</code> containing the decoded contents of
52 * the input, or <code>null</code>.
53 *
54 * @exception NullPointerException
55 * if <code>input</code> is <code>null</code>.
56 * @exception IOException
57 * if an error occurs during reading.
58 */
59 public static TBufferedImage read(File input) throws IOException {
60 if (input == null)
61 throw new NullPointerException("input == null!");
62
63 if (!input.canRead())
64 throw new IIOException("Can't read input file!");
65
66 ImageInputStream stream = ImageIO.createImageInputStream(input);
67 if (stream == null)
68 throw new IIOException("Can't create an ImageInputStream!");
69
70 TBufferedImage tbi = read(stream);
71 if (tbi == null)
72 stream.close();
73
74 return tbi;
75 }
76
77 /**
78 * Returns a <code>TBufferedImage</code> as the result of decoding a
79 * supplied <code>InputStream</code><br>
80 * with an <code>ImageReader</code> chosen automatically from among those
81 * currently registered.<br>
82 * The <code>InputStream</code> is wrapped in an
83 * <code>ImageInputStream</code>.<br>
84 * If no registered <code>ImageReader</code> claims to be able to read the
85 * resulting stream, <code>null</code> is returned.
86 *
87 * <p>
88 * The current cache settings from <code>getUseCache</code>and
89 * <code>getCacheDirectory</code><br>
90 * will be used to control caching in the <code>ImageInputStream</code> that
91 * is created.
92 *
93 * <p>
94 * This method does not attempt to locate <code>ImageReader</code>s that can
95 * read directly from an <code>InputStream</code>;<br>
96 * that may be accomplished using <code>IIORegistry</code> and
97 * <code>ImageReaderSpi</code>.
98 *
99 * <p>
100 * This method <em>does not</em> close the provided <code>InputStream</code>
101 * after the read operation has completed;<br>
102 * it is the responsibility of the caller to close the stream, if desired.
103 *
104 * @param input
105 * an <code>InputStream</code> to read from.
106 *
107 * @return a <code>TBufferedImage</code> containing the decoded contents of
108 * the input, or <code>null</code>.
109 *
110 * @exception NullPointerException
111 * if <code>input</code> is <code>null</code>.
112 * @exception IOException
113 * if an error occurs during reading.
114 */
115 public static TBufferedImage read(InputStream input) throws IOException {
116 if (input == null)
117 throw new NullPointerException("input == null!");
118
119 ImageInputStream stream = ImageIO.createImageInputStream(input);
120 TBufferedImage tbi = read(stream);
121 if (tbi == null)
122 stream.close();
123
124 return tbi;
125 }
126
127 /**
128 * Returns a <code>TBufferedImage</code> as the result of decoding a
129 * supplied <code>URL</code><br>
130 * with an <code>ImageReader</code> chosen automatically from among those
131 * currently registered.<br>
132 * An <code>InputStream</code> is obtained from the <code>URL</code>, which
133 * is wrapped in an <code>ImageInputStream</code>.<br>
134 * If no registered <code>ImageReader</code> claims to be able to read the
135 * resulting stream, <code>null</code> is returned.
136 *
137 * <p>
138 * The current cache settings from <code>getUseCache</code>and
139 * <code>getCacheDirectory</code><br>
140 * will be used to control caching in the <code>ImageInputStream</code> that
141 * is created.
142 *
143 * <p>
144 * This method does not attempt to locate <code>ImageReader</code>s that can
145 * read directly from a <code>URL</code>; that may be accomplished using
146 * <code>IIORegistry</code> and <code>ImageReaderSpi</code>.
147 *
148 * @param input
149 * a <code>URL</code> to read from.
150 *
151 * @return a <code>TBufferedImage</code> containing the decoded contents of
152 * the input, or <code>null</code>.
153 *
154 * @exception NullPointerException
155 * if <code>input</code> is <code>null</code>.
156 * @exception IOException
157 * if an error occurs during reading.
158 */
159 public static TBufferedImage read(URL input) throws IOException {
160 if (input == null)
161 throw new NullPointerException("input == null!");
162
163 InputStream istream = null;
164 try {
165 istream = input.openStream();
166 } catch (IOException e) {
167 throw new IIOException("Can't get input stream from URL!", e);
168 }
169
170 ImageInputStream stream = ImageIO.createImageInputStream(istream);
171 TBufferedImage tbi;
172 try {
173 tbi = read(stream);
174 if (tbi == null)
175 stream.close();
176
177 } finally {
178 istream.close();
179 }
180 return tbi;
181 }
182
183 /**
184 * Returns a <code>TBufferedImage</code> as the result of decoding a
185 * supplied <code>ImageInputStream</code><br>
186 * with an <code>ImageReader</code> chosen automatically from among those
187 * currently registered.<br>
188 * If no registered <code>ImageReader</code> claims to be able to read the
189 * stream, <code>null</code> is returned.
190 *
191 * <p>
192 * Unlike most other methods in this class, this method <em>does</em> close
193 * the provided <code>ImageInputStream</code><br>
194 * after the read operation has completed, unless <code>null</code> is
195 * returned,<br>
196 * in which case this method <em>does not</em> close the stream.
197 *
198 * @param stream
199 * an <code>ImageInputStream</code> to read from.
200 *
201 * @return a <code>TBufferedImage</code> containing the decoded contents of
202 * the input, or <code>null</code>.
203 *
204 * @exception NullPointerException
205 * if <code>stream</code> is <code>null</code>.
206 * @exception IOException
207 * if an error occurs during reading.
208 */
209 public static TBufferedImage read(ImageInputStream stream) throws IOException {
210 if (stream == null)
211 throw new NullPointerException("stream == null!");
212
213 Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);
214 if (!iter.hasNext())
215 return null;
216
217 ImageReader reader = (ImageReader) iter.next();
218 ImageReadParam param = reader.getDefaultReadParam();
219 reader.setInput(stream, true, false);
220 BufferedImage image;
221 IIOMetadata metadata;
222 try {
223 image = reader.read(0, param);
224 metadata = reader.getImageMetadata(0);
225
226 } finally {
227 reader.dispose();
228 stream.close();
229 }
230 return new TBufferedImage(image, new TImageMetadata(metadata));
231 }
232
233 public static boolean write(TBufferedImage tbi, File output) throws IOException {
234 if (tbi == null)
235 throw new NullPointerException("timage == null!");
236
237 if (output == null)
238 throw new NullPointerException("output == null!");
239
240 ImageOutputStream stream = null;
241 try {
242 output.delete();
243 stream = ImageIO.createImageOutputStream(output);
244
245 } catch (IOException e) {
246 throw new IIOException("Can't create output stream!", e);
247 }
248
249 boolean val;
250 try {
251 val = write(tbi, stream);
252 } finally {
253 stream.close();
254 }
255 return val;
256 }
257
258 public static boolean write(TBufferedImage tbi, ImageOutputStream output) throws IOException {
259 if (tbi == null)
260 throw new NullPointerException("tbi == null!");
261
262 if (output == null)
263 throw new NullPointerException("output == null!");
264
265 ImageWriter writer = null;
266 ImageTypeSpecifier type = ImageTypeSpecifier.createFromRenderedImage(tbi.getBufferedImage());
267 Iterator<ImageWriter> iter = ImageIO.getImageWriters(type, "png");
268 if (iter.hasNext())
269 writer = (ImageWriter) iter.next();
270
271 if (writer == null)
272 return false;
273
274 writer.setOutput(output);
275 try {
276 IIOMetadata metadata = tbi.getMetadata() == null ? null : tbi.getMetadata().toPngMetadata();
277 writer.write(new IIOImage(tbi.getBufferedImage(), null, metadata));
278
279 } finally {
280 writer.dispose();
281 output.flush();
282 }
283 return true;
284 }
285
286 }