001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.imaging; 018 019import java.io.PrintWriter; 020import java.io.StringWriter; 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.List; 024import java.util.logging.Logger; 025 026/** 027 * ImageInfo represents a collection of basic properties of an image, such as width, height, format, bit depth, etc. 028 */ 029public class ImageInfo { 030 031 public enum ColorType { 032 BW("Black and White"), GRAYSCALE("Grayscale"), RGB("RGB"), CMYK("CMYK"), YCbCr("YCbCr"), YCCK("YCCK"), YCC("YCC"), OTHER("Other"), UNKNOWN("Unknown"); 033 034 private final String description; 035 036 ColorType(final String description) { 037 this.description = description; 038 } 039 040 @Override 041 public String toString() { 042 return description; 043 } 044 } 045 046 public enum CompressionAlgorithm { 047 UNKNOWN("Unknown"), NONE("None"), LZW("LZW"), PACKBITS("PackBits"), JPEG_TIFF_OBSOLETE("JPEG Obsolete (TIFF only)"), JPEG("JPEG"), 048 RLE("RLE: Run-Length Encoding"), ADAPTIVE_RLE("Adaptive RLE"), PSD("Photoshop"), PNG_FILTER("PNG Filter"), 049 CCITT_GROUP_3("CCITT Group 3 1-Dimensional Modified Huffman run-length encoding."), CCITT_GROUP_4("CCITT Group 4"), CCITT_1D("CCITT 1D"), 050 DEFLATE("DEFLATE (ZIP)"); 051 052 private final String description; 053 054 CompressionAlgorithm(final String description) { 055 this.description = description; 056 } 057 058 @Override 059 public String toString() { 060 return description; 061 } 062 } 063 064 private static final Logger LOGGER = Logger.getLogger(ImageInfo.class.getName()); 065 066 private final String formatDetails; // version 067 068 private final int bitsPerPixel; 069 private final List<String> comments; 070 071 private final ImageFormat format; 072 private final String formatName; 073 private final int height; 074 private final String mimeType; 075 076 private final int numberOfImages; 077 private final int physicalHeightDpi; 078 private final float physicalHeightInch; 079 private final int physicalWidthDpi; 080 private final float physicalWidthInch; 081 private final int width; 082 private final boolean progressive; 083 private final boolean transparent; 084 085 private final boolean usesPalette; 086 087 private final ColorType colorType; 088 089 private final CompressionAlgorithm compressionAlgorithm; 090 091 public ImageInfo(final String formatDetails, final int bitsPerPixel, final List<String> comments, final ImageFormat format, final String formatName, 092 final int height, final String mimeType, final int numberOfImages, final int physicalHeightDpi, final float physicalHeightInch, 093 final int physicalWidthDpi, final float physicalWidthInch, final int width, final boolean progressive, final boolean transparent, 094 final boolean usesPalette, final ColorType colorType, final CompressionAlgorithm compressionAlgorithm) { 095 this.formatDetails = formatDetails; 096 097 this.bitsPerPixel = bitsPerPixel; 098 this.comments = comments == null ? Collections.emptyList() : Collections.unmodifiableList(comments); 099 100 this.format = format; 101 this.formatName = formatName; 102 this.height = height; 103 this.mimeType = mimeType; 104 105 this.numberOfImages = numberOfImages; 106 this.physicalHeightDpi = physicalHeightDpi; 107 this.physicalHeightInch = physicalHeightInch; 108 this.physicalWidthDpi = physicalWidthDpi; 109 this.physicalWidthInch = physicalWidthInch; 110 this.width = width; 111 this.progressive = progressive; 112 113 this.transparent = transparent; 114 this.usesPalette = usesPalette; 115 116 this.colorType = colorType; 117 this.compressionAlgorithm = compressionAlgorithm; 118 } 119 120 public void dump() { 121 LOGGER.fine(toString()); 122 } 123 124 /** 125 * Returns the bits per pixel of the image data. 126 * 127 * @return bits per pixel of the image data. 128 */ 129 public int getBitsPerPixel() { 130 return bitsPerPixel; 131 } 132 133 /** 134 * Returns the {@link org.apache.commons.imaging.ImageInfo.ColorType} of the image. 135 * 136 * @return image color type. 137 */ 138 public ColorType getColorType() { 139 return colorType; 140 } 141 142 /** 143 * Returns a list of comments from the image file. 144 * 145 * <p> 146 * This is mostly obsolete. 147 * </p> 148 * 149 * @return A list of comments. 150 */ 151 public List<String> getComments() { 152 return new ArrayList<>(comments); 153 } 154 155 /** 156 * Returns a description of the compression algorithm, if any. 157 * 158 * @return compression algorithm description. 159 */ 160 public CompressionAlgorithm getCompressionAlgorithm() { 161 return compressionAlgorithm; 162 } 163 164 /** 165 * Returns the image file format, ie. ImageFormat.IMAGE_FORMAT_PNG. 166 * 167 * <p> 168 * Returns ImageFormat.IMAGE_FORMAT_UNKNOWN if format is unknown. 169 * </p> 170 * 171 * @return a constant defined in ImageFormat. 172 * @see ImageFormats 173 */ 174 public ImageFormat getFormat() { 175 return format; 176 } 177 178 /** 179 * Returns a description of the file format, ie. format version. 180 * 181 * @return file format description. 182 */ 183 public String getFormatDetails() { 184 return formatDetails; 185 } 186 187 /** 188 * Returns a string with the name of the image file format. 189 * 190 * @return the name of the image file format. 191 * @see #getFormat() 192 */ 193 public String getFormatName() { 194 return formatName; 195 } 196 197 /** 198 * Returns the height of the image in pixels. 199 * 200 * @return image height in pixels. 201 * @see #getWidth() 202 */ 203 public int getHeight() { 204 return height; 205 } 206 207 /** 208 * Returns the MIME type of the image. 209 * 210 * @return image MIME type. 211 * @see #getFormat() 212 */ 213 public String getMimeType() { 214 return mimeType; 215 } 216 217 /** 218 * Returns the number of images in the file. 219 * 220 * <p> 221 * Applies mostly to GIF and TIFF; reading PSD/Photoshop layers is not supported, and Jpeg/JFIF EXIF thumbnails are not included in this count. 222 * </p> 223 * 224 * @return number of images in the file. 225 */ 226 public int getNumberOfImages() { 227 return numberOfImages; 228 } 229 230 /** 231 * Returns horizontal dpi of the image, if available. 232 * 233 * <p> 234 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 72). 235 * </p> 236 * 237 * @return returns -1 if not present. 238 */ 239 public int getPhysicalHeightDpi() { 240 return physicalHeightDpi; 241 } 242 243 /** 244 * Returns physical height of the image in inches, if available. 245 * 246 * <p> 247 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 72). 248 * </p> 249 * 250 * @return returns -1 if not present. 251 */ 252 public float getPhysicalHeightInch() { 253 return physicalHeightInch; 254 } 255 256 /** 257 * Returns vertical dpi of the image, if available. 258 * 259 * <p> 260 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 72). 261 * </p> 262 * 263 * @return returns -1 if not present. 264 */ 265 public int getPhysicalWidthDpi() { 266 return physicalWidthDpi; 267 } 268 269 /** 270 * Returns physical width of the image in inches, if available. 271 * 272 * <p> 273 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 72). 274 * </p> 275 * 276 * @return returns -1 if not present. 277 */ 278 public float getPhysicalWidthInch() { 279 return physicalWidthInch; 280 } 281 282 /** 283 * Returns the width of the image in pixels. 284 * 285 * @return image width in pixels. 286 * @see #getHeight() 287 */ 288 public int getWidth() { 289 return width; 290 } 291 292 /** 293 * Returns true if the image is progressive or interlaced. 294 * 295 * @return {@code true} if the image is progressive or interlaced, {@code false} otherwise. 296 */ 297 public boolean isProgressive() { 298 return progressive; 299 } 300 301 /** 302 * Returns true if the image has transparency. 303 * 304 * @return {@code true} if the image has transparency, {@code false} otherwise. 305 */ 306 public boolean isTransparent() { 307 return transparent; 308 } 309 310 @Override 311 public String toString() { 312 try { 313 final StringWriter sw = new StringWriter(); 314 final PrintWriter pw = new PrintWriter(sw); 315 316 toString(pw, ""); 317 pw.flush(); 318 319 return sw.toString(); 320 } catch (final Exception e) { 321 return "Image Data: Error"; 322 } 323 } 324 325 public void toString(final PrintWriter pw, final String prefix) { 326 pw.println("Format Details: " + formatDetails); 327 328 pw.println("Bits Per Pixel: " + bitsPerPixel); 329 pw.println("Comments: " + comments.size()); 330 for (int i = 0; i < comments.size(); i++) { 331 final String s = comments.get(i); 332 pw.println("\t" + i + ": '" + s + "'"); 333 334 } 335 pw.println("Format: " + format.getName()); 336 pw.println("Format Name: " + formatName); 337 pw.println("Compression Algorithm: " + compressionAlgorithm); 338 pw.println("Height: " + height); 339 pw.println("MimeType: " + mimeType); 340 pw.println("Number Of Images: " + numberOfImages); 341 pw.println("Physical Height Dpi: " + physicalHeightDpi); 342 pw.println("Physical Height Inch: " + physicalHeightInch); 343 pw.println("Physical Width Dpi: " + physicalWidthDpi); 344 pw.println("Physical Width Inch: " + physicalWidthInch); 345 pw.println("Width: " + width); 346 pw.println("Is Progressive: " + progressive); 347 pw.println("Is Transparent: " + transparent); 348 349 pw.println("Color Type: " + colorType.toString()); 350 pw.println("Uses Palette: " + usesPalette); 351 352 pw.flush(); 353 354 } 355 356 /** 357 * Returns true if the image uses a palette. 358 * 359 * @return {@code true} if the image uses a palette, {@code false} otherwise. 360 */ 361 public boolean usesPalette() { 362 return usesPalette; 363 } 364 365}