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