⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageinfo.java

📁 开源的HTML文本编辑器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * ImageInfo.java * * Version 1.9 * * A Java class to determine image width, height and color depth for * a number of image file formats. * * Written by Marco Schmidt  * * Contributed to the Public Domain. */package org.devlib.schmidt.imageinfo;import java.io.DataInput;import java.io.FileInputStream;import java.io.InputStream;import java.io.IOException;import java.net.URL;import java.util.Vector;/** * Get file format, image resolution, number of bits per pixel and optionally  * number of images, comments and physical resolution from  * JPEG, GIF, BMP, PCX, PNG, IFF, RAS, PBM, PGM, PPM and PSD files  * (or input streams). * <p> * Use the class like this: * <pre> * ImageInfo ii = new ImageInfo(); * ii.setInput(in); // in can be InputStream or RandomAccessFile * ii.setDetermineImageNumber(true); // default is false * ii.setCollectComments(true); // default is false * if (!ii.check()) { *   System.err.println("Not a supported image file format."); *   return; * } * System.out.println(ii.getFormatName() + ", " + ii.getMimeType() +  *   ", " + ii.getWidth() + " x " + ii.getHeight() + " pixels, " +  *   ii.getBitsPerPixel() + " bits per pixel, " + ii.getNumberOfImages() + *   " image(s), " + ii.getNumberOfComments() + " comment(s)."); *  // there are other properties, check out the API documentation * </pre> * You can also use this class as a command line program. * Call it with a number of image file names and URLs as parameters: * <pre> *   java ImageInfo *.jpg *.png *.gif http://somesite.tld/image.jpg * </pre> * or call it without parameters and pipe data to it: * <pre> *   java ImageInfo &lt; image.jpg   * </pre> * <p> * Known limitations: * <ul> * <li>When the determination of the number of images is turned off, GIF bits  *  per pixel are only read from the global header. *  For some GIFs, local palettes change this to a typically larger *  value. To be certain to get the correct color depth, call *  setDetermineImageNumber(true) before calling check(). *  The complete scan over the GIF file will take additional time.</li> * <li>Transparency information is not included in the bits per pixel count. *  Actually, it was my decision not to include those bits, so it's a feature! ;-)</li> * </ul> * <p> * Requirements: * <ul> * <li>Java 1.1 or higher</li> * </ul> * <p> * The latest version can be found at <a href="http://schmidt.devlib.org/image-info/">http://schmidt.devlib.org/image-info/</a>. * <p> * Written by Marco Schmidt. * <p> * This class is contributed to the Public Domain. * Use it at your own risk. * <p> * <a name="history">History</a>: * <ul> * <li><strong>2001-08-24</strong> Initial version.</li> * <li><strong>2001-10-13</strong> Added support for the file formats BMP and PCX.</li> * <li><strong>2001-10-16</strong> Fixed bug in read(int[], int, int) that returned * <li><strong>2002-01-22</strong> Added support for file formats Amiga IFF and Sun Raster (RAS).</li> * <li><strong>2002-01-24</strong> Added support for file formats Portable Bitmap / Graymap / Pixmap (PBM, PGM, PPM) and Adobe Photoshop (PSD). *   Added new method getMimeType() to return the MIME type associated with a particular file format.</li> * <li><strong>2002-03-15</strong> Added support to recognize number of images in file. Only works with GIF. *   Use {@link #setDetermineImageNumber} with <code>true</code> as argument to identify animated GIFs *   ({@link #getNumberOfImages()} will return a value larger than <code>1</code>).</li> * <li><strong>2002-04-10</strong> Fixed a bug in the feature 'determine number of images in animated GIF' introduced with version 1.1. *   Thanks to Marcelo P. Lima for sending in the bug report.  *   Released as 1.1.1.</li> * <li><strong>2002-04-18</strong> Added {@link #setCollectComments(boolean)}.  *  That new method lets the user specify whether textual comments are to be   *  stored in an internal list when encountered in an input image file / stream. *  Added two methods to return the physical width and height of the image in dpi:  *   {@link #getPhysicalWidthDpi()} and {@link #getPhysicalHeightDpi()}. *  If the physical resolution could not be retrieved, these methods return <code>-1</code>. *  </li> * <li><strong>2002-04-23</strong> Added support for the new properties physical resolution and *   comments for some formats. Released as 1.2.</li> * <li><strong>2002-06-17</strong> Added support for SWF, sent in by Michael Aird. *  Changed checkJpeg() so that other APP markers than APP0 will not lead to a failure anymore. *  Released as 1.3.</li> * <li><strong>2003-07-28</strong> Bug fix - skip method now takes return values into consideration. *  Less bytes than necessary may have been skipped, leading to flaws in the retrieved information in some cases. *  Thanks to Bernard Bernstein for pointing that out. *  Released as 1.4.</li> * <li><strong>2004-02-29</strong> Added support for recognizing progressive JPEG and *  interlaced PNG and GIF. A new method {@link #isProgressive()} returns whether ImageInfo *  has found that the storage type is progressive (or interlaced).  *  Thanks to Joe Germuska for suggesting the feature. *  Bug fix: BMP physical resolution is now correctly determined. *  Released as 1.5.</li> * <li><strong>2004-11-30</strong> Bug fix: recognizing progressive GIFs  * (interlaced in GIF terminology) did not work (thanks to Franz Jeitler for  *   pointing this out). Now it should work, but only if the number of images is determined. *  This is because information on interlacing is stored in a local image header. *  In theory, different images could be stored interlaced and non-interlaced in one  *  file. However, I think  that's unlikely. Right now, the last image in the GIF file  *  that is examined by ImageInfo is used for the "progressive" status.</li> * <li><strong>2005-01-02</strong> Some code clean up (unused methods and variables *  commented out, missing javadoc comments, etc.). Thanks to George Sexton for a long list. *  Removed usage of Boolean.toString because *  it's a Java 1.4+ feature (thanks to Gregor Dupont). *  Changed delimiter character in compact output from semicolon to tabulator * (for better integration with cut(1) and other Unix tools). *  Added some points to the <a href="http://schmidt.devlib.org/image-info/index.html#knownissues">'Known *  issues' section of the website</a>.  *  Released as 1.6.</li> * <li><strong>2005-07-26</strong> Removed code to identify Flash (SWF) files. *  Has repeatedly led to problems and support requests, and I don't know the *  format and don't have the time and interest to fix it myself. *  I repeatedly included fixes by others which didn't work for some people. *  I give up on SWF. Please do not contact me about it anymore. *  Set package of ImageInfo class to org.devlib.schmidt.imageinfo (a package *  was repeatedly requested by some users). *  Released as 1.7.</li> *  <li><strong>2006-02-23</strong> Removed Flash helper methods which weren't used elsewhere. *   Updated skip method which tries "read" whenever "skip(Bytes)" returns a result of 0. *   The old method didn't work with certain input stream types on truncated data streams. *   Thanks to Martin Leidig for reporting this and sending in code. *   Released as 1.8.</li> *  </li> *  <li><strong>2006-11-13</strong> Removed check that made ImageInfo report JPEG APPx *   markers smaller than 14 bytes as files in unknown format. Such JPEGs seem to be *   generated by Google's Picasa application. First reported with fix by  *   Karl von Randow. Released as 1.9.</li>   * </ul> * @author Marco Schmidt */@SuppressWarnings("unchecked")public class ImageInfo {	/**	 * Return value of {@link #getFormat()} for JPEG streams.	 * ImageInfo can extract physical resolution and comments	 * from JPEGs (only from APP0 headers).	 * Only one image can be stored in a file.	 * It is determined whether the JPEG stream is progressive 	 * (see {@link #isProgressive()}).	 */	public static final int FORMAT_JPEG = 0;	/**	 * Return value of {@link #getFormat()} for GIF streams.	 * ImageInfo can extract comments from GIFs and count the number	 * of images (GIFs with more than one image are animations).	 * It is determined whether the GIF stream is interlaced (see {@link #isProgressive()}).	 */	public static final int FORMAT_GIF = 1;	/**	 * Return value of {@link #getFormat()} for PNG streams.	 * PNG only supports one image per file.	 * Both physical resolution and comments can be stored with PNG,	 * but ImageInfo is currently not able to extract those.	 * It is determined whether the PNG stream is interlaced (see {@link #isProgressive()}).	 */	public static final int FORMAT_PNG = 2;	/**	 * Return value of {@link #getFormat()} for BMP streams.	 * BMP only supports one image per file.	 * BMP does not allow for comments.	 * The physical resolution can be stored.	 */	public static final int FORMAT_BMP = 3;	/**	 * Return value of {@link #getFormat()} for PCX streams.	 * PCX does not allow for comments or more than one image per file.	 * However, the physical resolution can be stored.	 */	public static final int FORMAT_PCX = 4;	/**	 * Return value of {@link #getFormat()} for IFF streams.	 */	public static final int FORMAT_IFF = 5;	/**	 * Return value of {@link #getFormat()} for RAS streams.	 * Sun Raster allows for one image per file only and is not able to	 * store physical resolution or comments.	 */	public static final int FORMAT_RAS = 6;	/** Return value of {@link #getFormat()} for PBM streams. */	public static final int FORMAT_PBM = 7;	/** Return value of {@link #getFormat()} for PGM streams. */	public static final int FORMAT_PGM = 8;	/** Return value of {@link #getFormat()} for PPM streams. */	public static final int FORMAT_PPM = 9;	/** Return value of {@link #getFormat()} for PSD streams. */	public static final int FORMAT_PSD = 10;/*	public static final int COLOR_TYPE_UNKNOWN = -1;	public static final int COLOR_TYPE_TRUECOLOR_RGB = 0;	public static final int COLOR_TYPE_PALETTED = 1;	public static final int COLOR_TYPE_GRAYSCALE= 2;	public static final int COLOR_TYPE_BLACK_AND_WHITE = 3;*/	/**	 * The names of all supported file formats.	 * The FORMAT_xyz int constants can be used as index values for	 * this array.	 */	private static final String[] FORMAT_NAMES =		{"JPEG", "GIF", "PNG", "BMP", "PCX", 		 "IFF", "RAS", "PBM", "PGM", "PPM", 		 "PSD"};	/**	 * The names of the MIME types for all supported file formats.	 * The FORMAT_xyz int constants can be used as index values for	 * this array.	 */	private static final String[] MIME_TYPE_STRINGS =		{"image/jpeg", "image/gif", "image/png", "image/bmp", "image/pcx", 		 "image/iff", "image/ras", "image/x-portable-bitmap", "image/x-portable-graymap", "image/x-portable-pixmap", 		 "image/psd"};	private int width;	private int height;	private int bitsPerPixel;	//private int colorType = COLOR_TYPE_UNKNOWN;	private boolean progressive;	private int format;	private InputStream in;	private DataInput din;	private boolean collectComments = true;	private Vector comments;	private boolean determineNumberOfImages;	private int numberOfImages;	private int physicalHeightDpi;	private int physicalWidthDpi;	private void addComment(String s) {		if (comments == null) {			comments = new Vector();		}		comments.addElement(s);	}	/**	 * Call this method after you have provided an input stream or file	 * using {@link #setInput(InputStream)} or {@link #setInput(DataInput)}.	 * If true is returned, the file format was known and information	 * on the file's content can be retrieved using the various getXyz methods.	 * @return if information could be retrieved from input	 */	public boolean check() {		format = -1;		width = -1;		height = -1;		bitsPerPixel = -1;		numberOfImages = 1;		physicalHeightDpi = -1;		physicalWidthDpi = -1;		comments = null;		try {			int b1 = read() & 0xff;			int b2 = read() & 0xff;			if (b1 == 0x47 && b2 == 0x49) {				return checkGif();			}			else			if (b1 == 0x89 && b2 == 0x50) {				return checkPng();			}			else			if (b1 == 0xff && b2 == 0xd8) {				return checkJpeg();			}			else			if (b1 == 0x42 && b2 == 0x4d) {				return checkBmp();			}			else			if (b1 == 0x0a && b2 < 0x06) {				return checkPcx();			}			else			if (b1 == 0x46 && b2 == 0x4f) {				return checkIff();			}			else			if (b1 == 0x59 && b2 == 0xa6) {				return checkRas();			}			else			if (b1 == 0x50 && b2 >= 0x31 && b2 <= 0x36) {				return checkPnm(b2 - '0');			}			else			if (b1 == 0x38 && b2 == 0x42) {				return checkPsd();			}			else {				return false;			}		} catch (IOException ioe) {			return false;		}	}	private boolean checkBmp() throws IOException {		byte[] a = new byte[44];		if (read(a) != a.length) {			return false;		}		width = getIntLittleEndian(a, 16);		height = getIntLittleEndian(a, 20);		if (width < 1 || height < 1) {			return false;		}		bitsPerPixel = getShortLittleEndian(a, 26);		if (bitsPerPixel != 1 && bitsPerPixel != 4 &&		    bitsPerPixel != 8 && bitsPerPixel != 16 &&		    bitsPerPixel != 24 && bitsPerPixel != 32) {		    return false;		}		int x = (int)(getIntLittleEndian(a, 36) * 0.0254);		if (x > 0) {			setPhysicalWidthDpi(x);		}		int y = (int)(getIntLittleEndian(a, 40) * 0.0254);		if (y > 0) {			setPhysicalHeightDpi(y);		}		format = FORMAT_BMP;		return true;	}	private boolean checkGif() throws IOException {		final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61};		final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61};		byte[] a = new byte[11]; // 4 from the GIF signature + 7 from the global header		if (read(a) != 11) {			return false;		}		if ((!equals(a, 0, GIF_MAGIC_89A, 0, 4)) &&			(!equals(a, 0, GIF_MAGIC_87A, 0, 4))) {			return false;		}		format = FORMAT_GIF;		width = getShortLittleEndian(a, 4);		height = getShortLittleEndian(a, 6);		int flags = a[8] & 0xff;		bitsPerPixel = ((flags >> 4) & 0x07) + 1;		//progressive = (flags & 0x02) != 0;		if (!determineNumberOfImages) {			return true;		}		// skip global color palette		if ((flags & 0x80) != 0) {			int tableSize = (1 << ((flags & 7) + 1)) * 3;			skip(tableSize);		}		numberOfImages = 0;		int blockType;		do		{			blockType = read();			switch(blockType)			{				case(0x2c): // image separator				{					if (read(a, 0, 9) != 9) {						return false;					}					flags = a[8] & 0xff;					progressive = (flags & 0x40) != 0;					/*int locWidth = getShortLittleEndian(a, 4);					int locHeight = getShortLittleEndian(a, 6);					System.out.println("LOCAL: " + locWidth + " x " + locHeight);*/					int localBitsPerPixel = (flags & 0x07) + 1;					if (localBitsPerPixel > bitsPerPixel) {						bitsPerPixel = localBitsPerPixel;					}					if ((flags & 0x80) != 0) {						skip((1 << localBitsPerPixel) * 3);					}					skip(1); // initial code length					int n;					do					{						n = read();						if (n > 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -