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 public int getBitsPerPixel() { 143 return bitsPerPixel; 144 } 145 146 /** 147 * Returns a list of comments from the image file. 148 * <p/> 149 * This is mostly obsolete. 150 */ 151 public List<String> getComments() { 152 return new ArrayList<>(comments); 153 } 154 155 /** 156 * Returns the image file format, ie. ImageFormat.IMAGE_FORMAT_PNG. 157 * <p/> 158 * Returns ImageFormat.IMAGE_FORMAT_UNKNOWN if format is unknown. 159 * 160 * @return A constant defined in ImageFormat. 161 * @see ImageFormats 162 */ 163 public ImageFormat getFormat() { 164 return format; 165 } 166 167 /** 168 * Returns a string with the name of the image file format. 169 * 170 * @see #getFormat() 171 */ 172 public String getFormatName() { 173 return formatName; 174 } 175 176 /** 177 * Returns the height of the image in pixels. 178 * 179 * @see #getWidth() 180 */ 181 public int getHeight() { 182 return height; 183 } 184 185 /** 186 * Returns the MIME type of the image. 187 * 188 * @see #getFormat() 189 */ 190 public String getMimeType() { 191 return mimeType; 192 } 193 194 /** 195 * Returns the number of images in the file. 196 * <p> 197 * Applies mostly to GIF and TIFF; reading PSD/Photoshop layers is not 198 * supported, and Jpeg/JFIF EXIF thumbnails are not included in this count. 199 */ 200 public int getNumberOfImages() { 201 return numberOfImages; 202 } 203 204 /** 205 * Returns horizontal dpi of the image, if available. 206 * <p> 207 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg 208 * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 209 * 72). 210 * 211 * @return returns -1 if not present. 212 */ 213 public int getPhysicalHeightDpi() { 214 return physicalHeightDpi; 215 } 216 217 /** 218 * Returns physical height of the image in inches, if available. 219 * <p> 220 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg 221 * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 222 * 72). 223 * 224 * @return returns -1 if not present. 225 */ 226 public float getPhysicalHeightInch() { 227 return physicalHeightInch; 228 } 229 230 /** 231 * Returns vertical dpi of the image, if available. 232 * <p> 233 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg 234 * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 235 * 72). 236 * 237 * @return returns -1 if not present. 238 */ 239 public int getPhysicalWidthDpi() { 240 return physicalWidthDpi; 241 } 242 243 /** 244 * Returns physical width of the image in inches, if available. 245 * <p> 246 * Applies to TIFF (optional), BMP (always), GIF (constant: 72), Jpeg 247 * (optional), PNG (optional), PNM (constant: 72), PSD/Photoshop (constant: 248 * 72). 249 * 250 * @return returns -1 if not present. 251 */ 252 public float getPhysicalWidthInch() { 253 return physicalWidthInch; 254 } 255 256 /** 257 * Returns the width of the image in pixels. 258 * 259 * @see #getHeight() 260 */ 261 public int getWidth() { 262 return width; 263 } 264 265 /** 266 * Returns true if the image is progressive or interlaced. 267 */ 268 public boolean isProgressive() { 269 return progressive; 270 } 271 272 /** 273 * Returns the {@link org.apache.commons.imaging.ImageInfo.ColorType} of the image. 274 */ 275 public ColorType getColorType() { 276 return colorType; 277 } 278 279 public void dump() { 280 LOGGER.fine(toString()); 281 } 282 283 @Override 284 public String toString() { 285 try { 286 final StringWriter sw = new StringWriter(); 287 final PrintWriter pw = new PrintWriter(sw); 288 289 toString(pw, ""); 290 pw.flush(); 291 292 return sw.toString(); 293 } catch (final Exception e) { 294 return "Image Data: Error"; 295 } 296 } 297 298 public void toString(final PrintWriter pw, final String prefix) { 299 pw.println("Format Details: " + formatDetails); 300 301 pw.println("Bits Per Pixel: " + bitsPerPixel); 302 pw.println("Comments: " + comments.size()); 303 for (int i = 0; i < comments.size(); i++) { 304 final String s = comments.get(i); 305 pw.println("\t" + i + ": '" + s + "'"); 306 307 } 308 pw.println("Format: " + format.getName()); 309 pw.println("Format Name: " + formatName); 310 pw.println("Compression Algorithm: " + compressionAlgorithm); 311 pw.println("Height: " + height); 312 pw.println("MimeType: " + mimeType); 313 pw.println("Number Of Images: " + numberOfImages); 314 pw.println("Physical Height Dpi: " + physicalHeightDpi); 315 pw.println("Physical Height Inch: " + physicalHeightInch); 316 pw.println("Physical Width Dpi: " + physicalWidthDpi); 317 pw.println("Physical Width Inch: " + physicalWidthInch); 318 pw.println("Width: " + width); 319 pw.println("Is Progressive: " + progressive); 320 pw.println("Is Transparent: " + transparent); 321 322 pw.println("Color Type: " + colorType.toString()); 323 pw.println("Uses Palette: " + usesPalette); 324 325 pw.flush(); 326 327 } 328 329 /** 330 * Returns a description of the file format, ie. format version. 331 */ 332 public String getFormatDetails() { 333 return formatDetails; 334 } 335 336 /** 337 * Returns true if the image has transparency. 338 */ 339 public boolean isTransparent() { 340 return transparent; 341 } 342 343 /** 344 * Returns true if the image uses a palette. 345 */ 346 public boolean usesPalette() { 347 return usesPalette; 348 } 349 350 /** 351 * Returns a description of the compression algorithm, if any. 352 */ 353 public CompressionAlgorithm getCompressionAlgorithm() { 354 return compressionAlgorithm; 355 } 356 357}