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

📄 extending.fm4.html

📁 IMAGEIO package 的使用说明jdk1.4新出的 包。有效改进图片读写方式。
💻 HTML
字号:
<!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.fm3.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/extending.fm3.html">PREV</a> | <a href="extending.fm5.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/extending.fm5.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="999064"><i>4.4	</i> Writing Writer Plug-ins</a></h2><blockquote><a name="999425"><!-- --></a><i><b> MyFormatImageWriterSpi</b></i></blockquote><blockquote><a name="999426"><!-- --></a>The <code>MyFormatImageWriterSpi</code> call plays a similar role to the <code>MyFormatImageReaderSpi</code> class discussed in the previous section. However, instead of being responsible for determining whether a given stream can be read, it must deterine whether an image in memory can be written. Rather than inspecting the image itself, an <code>ImageTypeSpecifier</code> is used so that writers may be selected before an actual image is available.<p></blockquote><blockquote><pre>package com.mycompany.imageio;import java.io.IOException;import java.util.Locale;import javax.imageio.ImageWriter;import javax.imageio.ImageTypeSpecifier;import javax.imageio.spi.ImageWriterSpi;import javax.imageio.stream.ImageInputStream;public class MyFormatImageWriterSpi extends ImageWriterSpi {	static final String vendorName = &#34;My Company&#34;;	static final String version = &#34;1.0_beta33_build9467&#34;;	static final String writerClassName =		&#34;com.mycompany.imageio.MyFormatImageWriter&#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[] readerSpiNames = {		&#34;com.mycompany.imageio.MyFormatImageReaderSpi&#34; };    	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 MyFormatImageWriterSpi() {		super(vendorName, version,		      names, suffixes, MIMETypes,		      writerClassName,		      STANDARD_OUTPUT_TYPE, // Write to ImageOutputStreams		      readerSpiNames,		      supportsStandardStreamMetadataFormat,		      nativeStreamMetadataFormatName,		      nativeStreamMetadataFormatClassName,		      extraStreamMetadataFormatNames,		      extraStreamMetadataFormatClassNames,		      supportsStandardImageMetadataFormat,		      nativeImageMetadataFormatName,		      nativeImageMetadataFormatClassName,		      extraImageMetadataFormatNames,		      extraImageMetadataFormatClassNames);	}	public boolean canEncodeImage(ImageTypeSpecifier imageType) {		int bands = imageType.getNumBands();		return bands == 1 || bands == 3;	}    	public String getDescription(Locale locale) {		// Localize as appropriate		return &#34;Description goes here&#34;;	}	public ImageWriter createWriterInstance(Object extension) {	    return new MyFormatImageWriter(this);	}}</pre></blockquote><blockquote><a name="1000429"><!-- --></a><i><b> MyFormatImageWriter</b></i></blockquote><blockquote><a name="999511"><!-- --></a><p></blockquote><blockquote><pre>package com.mycompany.imageio;import java.awt.Rectangle;import java.awt.image.Raster;import java.awt.image.RenderedImage;import java.io.IOException;import java.util.Iterator;import javax.imageio.IIOException;import javax.imageio.IIOImage;import javax.imageio.ImageTypeSpecifier;import javax.imageio.ImageWriteParam;import javax.imageio.ImageWriter;import javax.imageio.metadata.IIOMetadata;import javax.imageio.spi.ImageWriterSpi;import javax.imageio.stream.ImageOutputStream;public class MyFormatImageWriter extends ImageWriter {	ImageOutputStream stream = null;	public MyFormatImageWriter(ImageWriterSpi originatingProvider) {		super(originatingProvider);	} 	public void setOutput(Object output) {		super.setOutput(output);		if (output != null) {			if (!(output instanceof ImageOutputStream)) {				throw new IllegalArgumentException					(&#34;output not an ImageOutputStream!&#34;);			}			this.stream = (ImageOutputStream)output;		} else {			this.stream = null;		}	}</pre></blockquote><blockquote><a name="1000510"><!-- --></a>The <code>ImageWriteParam</code> returned by <code>getDefaultWriteParam</code> must be customized based on the writer&#39;s capabilities. Since this writer does not support tiling, progessive encoding, or compression, we pass in values of <code>false</code> or <code>null</code> as appropriate:<p></blockquote><blockquote><pre>	// Tiling, progressive encoding, compression are disabled by default	public ImageWriteParam getDefaultWriteParam() {		return new ImageWriteParam(getLocale());	}</pre></blockquote><blockquote><a name="1000534"><!-- --></a>The format only handles image metadata. The convertImageMetadata method does very little; it could be defined to interpret the metadata classes used by other plug-ins.<p><a name="1000956"><!-- --></a><p></blockquote><blockquote><pre>	public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {		return null;	}	public IIOMetadata		getDefaultImageMetadata(ImageTypeSpecifier imageType,		                        ImageWriteParam param) {		return new MyFormatMetadata();	}	public IIOMetadata convertStreamMetadata(IIOMetadata inData,	                                         ImageWriteParam param) {		return null;	}	public IIOMetadata convertImageMetadata(IIOMetadata inData,	                                        ImageTypeSpecifier imageType,	                                        ImageWriteParam param) {		// We only understand our own metadata		if (inData instanceof MyFormatMetadata) {			return inData;		} else {			return null;		}	}</pre></blockquote><blockquote><a name="1000544"><!-- --></a>The actual writing of the image requires first applying the source region, source bands, and subsampling factors from the <code>ImageWriteParam</code>. The source region and source bands may be handled by creating a child <code>Raster</code>. For simplicity, we extract a single <code>Raster</code> from the source image. If the source image is tiled, we can save memory by extracting smaller <code>Raster</code>s as needed.<p></blockquote><blockquote><pre>	public void write(IIOMetadata streamMetadata,	                  IIOImage image,	                  ImageWriteParam param) throws IIOException {		RenderedImage im = image.getRenderedImage();		Rectangle sourceRegion =			new Rectangle(0, 0, im.getWidth(), im.getHeight());		int sourceXSubsampling = 1;		int sourceYSubsampling = 1;		int[] sourceBands = null;		if (param != null) {			sourceRegion =				sourceRegion.intersection(param.getSourceRegion());			sourceXSubsampling = param.getSourceXSubsampling();			sourceYSubsampling = param.getSourceYSubsampling();			sourceBands = param.getSourceBands();			int subsampleXOffset = param.getSubsamplingXOffset();			int subsampleYOffset = param.getSubsamplingYOffset();			sourceRegion.x += subsampleXOffset;			sourceRegion.y += subsampleYOffset;			sourceRegion.width -= subsampleXOffset;			sourceRegion.height -= subsampleYOffset;		}		// Grab a Raster containing the region of interest		int width = sourceRegion.width;		int height = sourceRegion.height;		Raster imRas = im.getData(sourceRegion);		int numBands = imRas.getNumBands();		// Check that sourceBands values are in range		if (sourceBands != null) {			for (int i = 0; i &lt; sourceBands.length; i++) {				if (sourceBands[i] &gt;= numBands) {					throw new IllegalArgumentException(&#34;bad band!&#34;);				}			}		}		// Translate imRas to start at (0, 0) and subset the bands		imRas = imRas.createChild(sourceRegion.x, sourceRegion.y,		                          width, height,		                          0, 0,		                          sourceBands);		// Reduce width and height according to subsampling factors		width = (width + sourceXSubsampling - 1)/sourceXSubsampling;		height = (height + sourceYSubsampling - 1)/sourceYSubsampling;		// Assume 1 band image is grayscale, 3 band image is RGB		int colorType;		if (numBands == 1) {			colorType = MyFormatImageReader.COLOR_TYPE_GRAY;		} else if (numBands == 3) {			colorType = MyFormatImageReader.COLOR_TYPE_RGB;		} else {			throw new IIOException(&#34;Image must have 1 or 3 bands!&#34;);		}</pre></blockquote><blockquote><a name="1000564"><!-- --></a>Once the image dimensions and color type of the image have been ascertained, the plug-in is ready to write the file header:<p></blockquote><blockquote><pre>		try {			byte[] signature = {				(byte)&#39;m&#39;, (byte)&#39;y&#39;,  (byte)&#39;f&#39;, (byte)&#39;o&#39;,				(byte)&#39;r&#39;, (byte)&#39;m&#39;,  (byte)&#39;a&#39;, (byte)&#39;t&#39;			};			// Output header information			stream.write(signature);			stream.write(`\n&#39;);			stream.writeInt(width);			stream.writeInt(height);			stream.writeByte(colorType);			stream.write(`\n&#39;);			</pre></blockquote><blockquote><a name="1000568"><!-- --></a>Next, the plug-in extracts the image metadata from the <code>write</code> method&#39;s <code>IIOImage</code> argument, and attempts to convert it into a <code>MyFormatMetadata</code> object by calling <code>convertImageMetadata</code>. If the result is non-<code>null</code>, the keywords and values are extracted from the metadata and written to the output:<p></blockquote><blockquote><pre>			// Attempt to convert metadata, if present			IIOMetadata imd = image.getMetadata();			MyFormatMetadata metadata = null;			if (imd != null) {				ImageTypeSpecifier type =					ImageTypeSpecifier.createFromRenderedImage(im);				metadata =					(MyFormatMetadata)convertImageMetadata(imd,					                                       type,					                                       null);			}			// Output metadata if present			if (metadata != null) {				Iterator keywordIter = metadata.keywords.iterator();				Iterator valueIter = metadata.values.iterator();				while (keywordIter.hasNext()) {					String keyword = (String)keywordIter.next();					String value = (String)valueIter.next();										stream.writeUTF(keyword);					stream.write(`\n&#39;);					stream.writeUTF(value);					stream.write(`\n&#39;);				}			}			stream.writeUTF(&#34;END&#34;);			stream.write(`\n&#39;);</pre></blockquote><blockquote><a name="1000582"><!-- --></a>Finally, the plug-in is ready to begin writing the pixel data. The image <code>Raster</code> is copied into an int array, one row at a time using the <code>getPixels</code> method. Then these values are subsampled using the horizontal subsampling factor, and copied into a byte array, which is written to the output with a single write call. The source row is then incremented by the vertical subsampling factor until the end of the source region is reached, and the output stream is flushed:<p></blockquote><blockquote><pre>			// Output (subsampled) pixel values			int rowLength = width*numBands;			int xSkip = sourceXSubsampling*numBands;			int[] rowPixels = imRas.getPixels(0, 0, width, 1,			                                  (int[])null);			byte[] rowSamples = new byte[rowLength];			// Output every (sourceYSubsampling)^th row			for (int y = 0; y &lt; height; y += sourceYSubsampling) {				imRas.getPixels(0, y, width, 1, rowPixels);				// Subsample horizontally and convert to bytes				int count = 0;				for (int x = 0; x &lt; width; x += xSkip) {					if (colorType ==						MyFormatImageReader.COLOR_TYPE_GRAY) {						rowSamples[count++] = (byte)rowPixels[x];					} else {						rowSamples[count++] = (byte)rowPixels[x];						rowSamples[count++] =							(byte)rowPixels[x + 1];						rowSamples[count++] =							(byte)rowPixels[x + 2];					}				}				// Output a row&#39;s worth of bytes				stream.write(rowSamples, 0, width*numBands);			}			stream.flush();		} catch (IOException e) {			throw new IIOException(&#34;I/O error!&#34;, e);		}	}}</pre></blockquote><br><hr><!-- 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.fm3.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/extending.fm3.html">PREV</a> | <a href="extending.fm5.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/extending.fm5.html">NEXT</a> <!-- | <a href="copyright.fm.html">INDEX</a>  --><!-- /font --><hr><font size="-1"><i><A HREF="copyright.fm.html" tppabs="http://java.sun.com/j2se/1.4.2/docs/guide/imageio/spec/copyright.fm.html">Copyright</a> &#169 2001 Sun Microsystems, Inc. All Rights Reserved.</i></font><!-- This HTML file was created with Quadralay WebWorks Publisher 3.5.0 --><!-- by Suzette Pelouch --><!-- Last updated: Fri Apr 27 11:23:03 2001 --> </body><script language="JavaScript" src="s_code_remote.js" tppabs="http://java.sun.com/js/omi/jsc/s_code_remote.js"></script></html>

⌨️ 快捷键说明

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