View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.imaging;
18  
19  import java.io.PrintWriter;
20  import java.io.StringWriter;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.logging.Logger;
25  
26  /**
27   * ImageInfo represents a collection of basic properties of an image, such as
28   * width, height, format, bit depth, etc.
29   */
30  public class ImageInfo {
31  
32      public enum ColorType {
33          BW("Black and White"),
34          GRAYSCALE("Grayscale"),
35          RGB("RGB"),
36          CMYK("CMYK"),
37          YCbCr("YCbCr"),
38          YCCK("YCCK"),
39          YCC("YCC"),
40          OTHER("Other"),
41          UNKNOWN("Unknown");
42  
43          private final String description;
44  
45          ColorType(final String description) {
46              this.description = description;
47          }
48  
49          @Override
50          public String toString() {
51              return description;
52          }
53      }
54  
55      public enum CompressionAlgorithm {
56          UNKNOWN("Unknown"),
57          NONE("None"),
58          LZW("LZW"),
59          PACKBITS("PackBits"),
60          JPEG("JPEG"),
61          RLE("RLE: Run-Length Encoding"),
62          ADAPTIVE_RLE("Adaptive RLE"),
63          PSD("Photoshop"),
64          PNG_FILTER("PNG Filter"),
65          CCITT_GROUP_3("CCITT Group 3 1-Dimensional Modified Huffman run-length encoding."),
66          CCITT_GROUP_4("CCITT Group 4"),
67          CCITT_1D("CCITT 1D");
68  
69          private final String description;
70  
71          CompressionAlgorithm(final String description) {
72              this.description = description;
73          }
74  
75          @Override
76          public String toString() {
77              return description;
78          }
79      }
80  
81      private static final Logger LOGGER = Logger.getLogger(ImageInfo.class.getName());
82  
83      private final String formatDetails; // ie version
84  
85      private final int bitsPerPixel;
86      private final List<String> comments;
87  
88      private final ImageFormat format;
89      private final String formatName;
90      private final int height;
91      private final String mimeType;
92  
93      private final int numberOfImages;
94      private final int physicalHeightDpi;
95      private final float physicalHeightInch;
96      private final int physicalWidthDpi;
97      private final float physicalWidthInch;
98      private final int width;
99      private final boolean progressive;
100     private final boolean transparent;
101 
102     private final boolean usesPalette;
103 
104     private final ColorType colorType;
105 
106     private final CompressionAlgorithm compressionAlgorithm;
107 
108     public ImageInfo(final String formatDetails, final int bitsPerPixel,
109             final List<String> comments, final ImageFormat format, final String formatName,
110             final int height, final String mimeType, final int numberOfImages,
111             final int physicalHeightDpi, final float physicalHeightInch,
112             final int physicalWidthDpi, final float physicalWidthInch, final int width,
113             final boolean progressive, final boolean transparent, final boolean usesPalette,
114             final ColorType colorType, final CompressionAlgorithm compressionAlgorithm) {
115         this.formatDetails = formatDetails;
116 
117         this.bitsPerPixel = bitsPerPixel;
118         this.comments = comments == null ? Collections.emptyList() : Collections.unmodifiableList(comments);
119 
120         this.format = format;
121         this.formatName = formatName;
122         this.height = height;
123         this.mimeType = mimeType;
124 
125         this.numberOfImages = numberOfImages;
126         this.physicalHeightDpi = physicalHeightDpi;
127         this.physicalHeightInch = physicalHeightInch;
128         this.physicalWidthDpi = physicalWidthDpi;
129         this.physicalWidthInch = physicalWidthInch;
130         this.width = width;
131         this.progressive = progressive;
132 
133         this.transparent = transparent;
134         this.usesPalette = usesPalette;
135 
136         this.colorType = colorType;
137         this.compressionAlgorithm = compressionAlgorithm;
138     }
139 
140     /**
141      * Returns the bits per pixel of the image data.
142      *
143      * @return bits per pixel of the image data.
144      */
145     public int getBitsPerPixel() {
146         return bitsPerPixel;
147     }
148 
149     /**
150      * Returns a list of comments from the image file.
151      *
152      * <p>This is mostly obsolete.</p>
153      *
154      * @return A list of comments.
155      */
156     public List<String> getComments() {
157         return new ArrayList<>(comments);
158     }
159 
160     /**
161      * Returns the image file format, ie. ImageFormat.IMAGE_FORMAT_PNG.
162      *
163      * <p>Returns ImageFormat.IMAGE_FORMAT_UNKNOWN if format is unknown.</p>
164      *
165      * @return a constant defined in ImageFormat.
166      * @see ImageFormats
167      */
168     public ImageFormat getFormat() {
169         return format;
170     }
171 
172     /**
173      * Returns a string with the name of the image file format.
174      *
175      * @return the name of the image file format.
176      * @see #getFormat()
177      */
178     public String getFormatName() {
179         return formatName;
180     }
181 
182     /**
183      * Returns the height of the image in pixels.
184      *
185      * @return image height in pixels.
186      * @see #getWidth()
187      */
188     public int getHeight() {
189         return height;
190     }
191 
192     /**
193      * Returns the MIME type of the image.
194      *
195      * @return image MIME type.
196      * @see #getFormat()
197      */
198     public String getMimeType() {
199         return mimeType;
200     }
201 
202     /**
203      * Returns the number of images in the file.
204      *
205      * <p>Applies mostly to GIF and TIFF; reading PSD/Photoshop layers is not
206      * supported, and Jpeg/JFIF EXIF thumbnails are not included in this count.</p>
207      *
208      * @return number of images in the file.
209      */
210     public int getNumberOfImages() {
211         return numberOfImages;
212     }
213 
214     /**
215      * Returns horizontal dpi of the image, if available.
216      *
217      * <p>Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg
218      * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant:
219      * 72).</p>
220      *
221      * @return returns -1 if not present.
222      */
223     public int getPhysicalHeightDpi() {
224         return physicalHeightDpi;
225     }
226 
227     /**
228      * Returns physical height of the image in inches, if available.
229      *
230      * <p>Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg
231      * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant:
232      * 72).</p>
233      *
234      * @return returns -1 if not present.
235      */
236     public float getPhysicalHeightInch() {
237         return physicalHeightInch;
238     }
239 
240     /**
241      * Returns vertical dpi of the image, if available.
242      *
243      * <p>Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg
244      * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant:
245      * 72).</p>
246      *
247      * @return returns -1 if not present.
248      */
249     public int getPhysicalWidthDpi() {
250         return physicalWidthDpi;
251     }
252 
253     /**
254      * Returns physical width of the image in inches, if available.
255      *
256      * <p>Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg
257      * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant:
258      * 72).</p>
259      *
260      * @return returns -1 if not present.
261      */
262     public float getPhysicalWidthInch() {
263         return physicalWidthInch;
264     }
265 
266     /**
267      * Returns the width of the image in pixels.
268      *
269      * @return image width in pixels.
270      * @see #getHeight()
271      */
272     public int getWidth() {
273         return width;
274     }
275 
276     /**
277      * Returns true if the image is progressive or interlaced.
278      *
279      * @return {@code true} if the image is progressive or interlaced, {@code false} otherwise.
280      */
281     public boolean isProgressive() {
282         return progressive;
283     }
284 
285     /**
286      * Returns the {@link org.apache.commons.imaging.ImageInfo.ColorType} of the image.
287      *
288      * @return image color type.
289      */
290     public ColorType getColorType() {
291         return colorType;
292     }
293 
294     public void dump() {
295         LOGGER.fine(toString());
296     }
297 
298     @Override
299     public String toString() {
300         try {
301             final StringWriter sw = new StringWriter();
302             final PrintWriter pw = new PrintWriter(sw);
303 
304             toString(pw, "");
305             pw.flush();
306 
307             return sw.toString();
308         } catch (final Exception e) {
309             return "Image Data: Error";
310         }
311     }
312 
313     public void toString(final PrintWriter pw, final String prefix) {
314         pw.println("Format Details: " + formatDetails);
315 
316         pw.println("Bits Per Pixel: " + bitsPerPixel);
317         pw.println("Comments: " + comments.size());
318         for (int i = 0; i < comments.size(); i++) {
319             final String s = comments.get(i);
320             pw.println("\t" + i + ": '" + s + "'");
321 
322         }
323         pw.println("Format: " + format.getName());
324         pw.println("Format Name: " + formatName);
325         pw.println("Compression Algorithm: " + compressionAlgorithm);
326         pw.println("Height: " + height);
327         pw.println("MimeType: " + mimeType);
328         pw.println("Number Of Images: " + numberOfImages);
329         pw.println("Physical Height Dpi: " + physicalHeightDpi);
330         pw.println("Physical Height Inch: " + physicalHeightInch);
331         pw.println("Physical Width Dpi: " + physicalWidthDpi);
332         pw.println("Physical Width Inch: " + physicalWidthInch);
333         pw.println("Width: " + width);
334         pw.println("Is Progressive: " + progressive);
335         pw.println("Is Transparent: " + transparent);
336 
337         pw.println("Color Type: " + colorType.toString());
338         pw.println("Uses Palette: " + usesPalette);
339 
340         pw.flush();
341 
342     }
343 
344     /**
345      * Returns a description of the file format, ie. format version.
346      *
347      * @return file format description.
348      */
349     public String getFormatDetails() {
350         return formatDetails;
351     }
352 
353     /**
354      * Returns true if the image has transparency.
355      *
356      * @return {@code true} if the image has transparency, {@code false} otherwise.
357      */
358     public boolean isTransparent() {
359         return transparent;
360     }
361 
362     /**
363      * Returns true if the image uses a palette.
364      *
365      * @return {@code true} if the image uses a palette, {@code false} otherwise.
366      */
367     public boolean usesPalette() {
368         return usesPalette;
369     }
370 
371     /**
372      * Returns a description of the compression algorithm, if any.
373      *
374      * @return compression algorithm description.
375      */
376     public CompressionAlgorithm getCompressionAlgorithm() {
377         return compressionAlgorithm;
378     }
379 
380 }