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

📄 extending.fm3.html

📁 IMAGEIO package 的使用说明jdk1.4新出的 包。有效改进图片读写方式。
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html><head><title>Java Image I/O API Guide: 4 - Writing Image I/O Plug-ins</title></head><body bgcolor="#ffffff"> <table summary="layout" width="100%"><tr><td><!-- Bug in Communicator w/font: NavBar text disappears for Times 14pt pref. --><!-- font size="-1" --> <a href="imageio_guideTOC.fm.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/imageio_guideTOC.fm.html">CONTENTS</a> | <a href="extending.fm2.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/extending.fm2.html">PREV</a> | <a href="extending.fm4.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/extending.fm4.html">NEXT</a> <!-- | <a href="copyright.fm.html">INDEX</a>  --><!-- /font --></td><td align=right><i>Java<sup><font size="-1">TM</font></sup></font> Image I/O API Guide</i></td></tr></table><br> <p><hr size="8" width="35%" align="left" noshade><h2><a name="996884"><i>4.3	</i> Writing Reader Plug-Ins</a></h2><blockquote><a name="997096"><!-- --></a>A minimal reader plug-in consists of an <code>ImageReaderSpi</code> subclass, and an <code>ImageReader</code> subclass. Optionally, it may contain implementations of the <code>IIOMetadata</code> interface representing the stream and image metadata, and an <code>IIOMetadataFormat</code> object describing the structure of the metadata.<p><a name="997127"><!-- --></a>In the following sections, we will sketch out the implementation of a simple reader plug-in for a hypothetical format called &#34;MyFormat&#34;. It will consist of the classes <code>MyFormatImageReaderSpi</code>, <code>MyFormatImageReader</code>, and <code>MyFormatMetadata</code>.<p><a name="997678"><!-- --></a>The format itself is defined to begin with the characters `myformat\n&#39;, followed by two four-byte integers representing the width, height, and a single byte indicating the color type of the image, which may be either gray or RGB. Next, after a newline character, metadata values may stored as alternating lines containing a keyword and a value, terminated by the special keyword `END&#39;. The string values are stored using UTF8 encoding followed by a newline. Finally, the image samples are stored in left-to-right, top-to-bottom order as either byte grayscale values, or three bytes representing red, green, and blue.<p></blockquote><blockquote><a name="997365"><!-- --></a><i><b> <code>MyFormatImageReaderSpi</code></b></i></blockquote><blockquote><a name="996982"><!-- --></a>The <code>MyFormatImageReaderSpi</code> class provides information about the plug-in, including the vendor name, plug-in version string and description, format name, file suffixes associated with the format, MIME types associated with the format, input source classes that the plug-in can handle, and the <code>ImageWriterSpi</code>s of plug-ins that are able to interoperate specially with the reader. It also must provide an implementation of the <code>canDecodeInput</code> method, which is used to locate plug-ins based on the contents of a source image file.<p><a name="996983"><!-- --></a>The <code>ImageReaderSpi</code> class provides implementations of most of its methods. These methods mainly return the value of various protected instance variables, which the <code>MyFormatImageReaderSpi</code> may set directly or via the superclass constructor, as in the example below:<p></blockquote><blockquote><pre>package com.mycompany.imageio;import java.io.IOException;import java.util.Locale;import javax.imageio.ImageReader;import javax.imageio.spi.ImageReaderSpi;import javax.imageio.stream.ImageInputStream;public class MyFormatImageReaderSpi extends ImageReaderSpi {	static final String vendorName = &#34;My Company&#34;;	static final String version = &#34;1.0_beta33_build9467&#34;;	static final String readerClassName =		&#34;com.mycompany.imageio.MyFormatImageReader&#34;;	static final String[] names = { &#34;myformat&#34; };	static final String[] suffixes = { &#34;myf&#34; };	static final String[] MIMETypes = {		&#34;image/x-myformat&#34; };	static final String[] writerSpiNames = {		&#34;com.mycompany.imageio.MyFormatImageWriterSpi&#34; };	// Metadata formats, more information below	static final boolean supportsStandardStreamMetadataFormat = false;	static final String nativeStreamMetadataFormatName = null	static final String nativeStreamMetadataFormatClassName = null;	static final String[] extraStreamMetadataFormatNames = null;	static final String[] extraStreamMetadataFormatClassNames = null;	static final boolean supportsStandardImageMetadataFormat = false;	static final String nativeImageMetadataFormatName =		"com.mycompany.imageio.MyFormatMetadata_1.0";	static final String nativeImageMetadataFormatClassName =		"com.mycompany.imageio.MyFormatMetadata";	static final String[] extraImageMetadataFormatNames = null;	static final String[] extraImageMetadataFormatClassNames = null;	public MyFormatImageReaderSpi() {		super(vendorName, version,		      names, suffixes, MIMETypes,		      readerClassName,		      STANDARD_INPUT_TYPE, // Accept ImageInputStreams		      writerSpiNames,		      supportsStandardStreamMetadataFormat,		      nativeStreamMetadataFormatName,		      nativeStreamMetadataFormatClassName,		      extraStreamMetadataFormatNames,		      extraStreamMetadataFormatClassNames,		      supportsStandardImageMetadataFormat,		      nativeImageMetadataFormatName,		      extraImageMetadataFormatNames,		      extraImageMetadataFormatClassNames);		}		public String getDescription(Locale locale) {			// Localize as appropriate			return &#34;Description goes here&#34;;		}		public boolean canDecodeInput(Object input)			throws IOException {			// see below		}            public ImageReader createReaderInstance(Object extension) {                return new MyFormatImageReader(this);            }	}</pre></blockquote><blockquote><a name="997269"><!-- --></a>Most plug-ins need read only from <code>ImageInputStream</code> sources, since it is possible to &#34;wrap&#34; most other types of input with an appropriate <code>ImageInputStream</code>. However, it is possible for a plug-in to work directly with other <code>Object</code>s, for example an <code>Object</code> that provides an interface to a digital camera or scanner. This interface need not provide a &#34;stream&#34; view of the device at all. Rather, a plug-in that is aware of the interface may use it to drive the device directly.<p><a name="997281"><!-- --></a>The plug-in advertises which input classes it can handle via its <code>getInputTypes</code> method, which returns an array of <code>Class</code> objects. An implementation of <code>getInputTypes</code> is provided in the superclass, which returns the value of the <code>inputTypes</code> instance variable, which in turn is set by the seventh argument to the superclass constructor. The value used in the example above, <code>STANDARD_INPUT_TYPE</code>, is shorthand for an array containing the single element <code>javax.imageio.stream.ImageInputStream.class</code>, indicating that the plug-in accepts only <code>ImageInputStream</code>s.<p><a name="997095"><!-- --></a>The <code>canDecodeInput</code> method is responsible for determining two things: first, whether the input parameter is an instance of a class that the plug-in can understand, and second, whether the file contents appear to be in the format handled by the plug-in. 	It must leave its input in the same state as it was when it was passed in. For an <code>ImageInputStream</code> input source, the mark and reset methods may be used. For example, since files in the &#34;MyFormat&#34; format all begin with the characters `myformat&#39;, <code>canDecodeInput</code> may be implemented as:<p></blockquote><blockquote><pre>public boolean canDecodeInput(Object input) {	if (!(input instanceof ImageInputStream)) {		return false;	}	ImageInputStream stream = (ImageInputStream)input;	byte[] b = new byte[8];	try {		stream.mark();		stream.readFully(b);		stream.reset();	} catch (IOException e) {		return false;	}	// Cast unsigned character constants prior to comparison	return (b[0] == (byte)&#39;m&#39; &amp;&amp; b[1] == (byte)&#39;y&#39; &amp;&amp;	        b[2] == (byte)&#39;f&#39; &amp;&amp; b[3] == (byte)&#39;o&#39; &amp;&amp;	        b[4] == (byte)&#39;r&#39; &amp;&amp; b[5] == (byte)&#39;m&#39; &amp;&amp;			        b[6] == (byte)&#39;a&#39; &amp;&amp; b[7] == (byte)&#39;t&#39;);}</pre></blockquote><blockquote><a name="997310"><!-- --></a><i><b> <code>MyFormatImageReader</code></b></i></blockquote><blockquote><a name="998556"><!-- --></a>The heart of a reader plug-in is its extension of the <code>ImageReader</code> class. This class is responsible for responding to queries about the images actually stored in an input file or stream, as well as the actual reading of images, thumbnails, and metadata. For simplicity, we will ignore thumbnail images in this example.<p><a name="997445"><!-- --></a>A sketch of some of the methods of a hypothetical MyFormatImageReader class is shown below:<p></blockquote><blockquote><pre>package com.mycompany.imageio;public class MyFormatImageReader extends ImageReader {	ImageInputStream stream = null;	int width, height;	int colorType;		// Constants enumerating the values of colorType	static final int COLOR_TYPE_GRAY = 0;	static final int COLOR_TYPE_RGB = 1;	boolean gotHeader = false;	public MyFormatImageReader(ImageReaderSpi originatingProvider) {		super(originatingProvider);	}	public void setInput(Object input, boolean isStreamable) {		super.setInput(input, isStreamable);		if (input == null) {			this.stream = null;			return;		}		if (input instanceof ImageInputStream) {			this.stream = (ImageInputStream)input;		} else {			throw new IllegalArgumentException("bad input");		}	}	public int getNumImages(boolean allowSearch)		throws IIOException {		return 1; // format can only encode a single image	}	private void checkIndex(int imageIndex) {		if (imageIndex != 0) {			throw new IndexOutOfBoundsException("bad index");		}	}	public int getWidth(int imageIndex)		throws IIOException {		checkIndex(imageIndex); // must throw an exception if != 0		readHeader();		return width;	}	public int getHeight(int imageIndex)		throws IIOException {		checkIndex(imageIndex);		readHeader();		return height;	}</pre></blockquote><blockquote><a name="998040"><!-- --></a><i><b> The getImageTypes Method</b></i></blockquote><blockquote><a name="1001117"><!-- --></a>The reader is responsible for indicating what sorts of images may be used to hold the decoded output. The <code>ImageTypeSpecifier</code> class is used to hold a <code>SampleModel</code> and <code>ColorModel</code> indicating a legal image layout. The <code>getImageTypes</code> method returns an <code>Iterator</code> of <code>ImageTypeSpecifier</code>s:<p></blockquote><blockquote><pre>	public Iterator getImageTypes(int imageIndex)		throws IIOException {		checkIndex(imageIndex);		readHeader();		ImageTypeSpecifier imageType = null;		int datatype = DataBuffer.TYPE_BYTE;		java.util.List l = new ArrayList();		switch (colorType) {		case COLOR_TYPE_GRAY:			imageType = ImageTypeSpecifier.createGrayscale(8,			                                               datatype,			                                               false);			break;		case COLOR_TYPE_RGB:			ColorSpace rgb =				ColorSpace.getInstance(ColorSpace.CS_sRGB);			int[] bandOffsets = new int[3];			bandOffsets[0] = 0;			bandOffsets[1] = 1;			bandOffsets[2] = 2;			imageType =				ImageTypeSpecifier.createInterleaved(rgb,				                                     bandOffsets,				                                     datatype,				                                     false,				                                     false);			break;						}		l.add(imageType);		return l.iterator();	}</pre></blockquote><blockquote><a name="1001120"><!-- --></a><i><b> Parsing the Image Header</b></i></blockquote><blockquote><a name="997490"><!-- --></a>Several of the methods above depend on a <code>readHeader</code> method, which is responsible for reading enough of the input stream to determine the width, height, and layout of the image. <code>readHeader</code> is defined so it is safe to be called multiple times (note that we are not concerned with multi-threaded access):<p></blockquote><blockquote><pre>	public void readHeader() {		if (gotHeader) {			return;		}		gotHeader = true;		if (stream == null) {			throw new IllegalStateException("No input stream");		}

⌨️ 快捷键说明

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