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

📄 extending.fm3.html

📁 IMAGEIO package 的使用说明jdk1.4新出的 包。有效改进图片读写方式。
💻 HTML
📖 第 1 页 / 共 3 页
字号:
		// Read `myformat\n&#39; from the stream		byte[] signature = new byte[9];		try {			stream.readFully(signature);		} catch (IOException e) {			throw new IIOException(&#34;Error reading signature&#34;, e);		}		if (signature[0] != (byte)&#39;m&#39; || ...) { // etc.			throw new IIOException("Bad file signature!&#34;);		}		// Read width, height, color type, newline		try {			this.width = stream.readInt();			this.height = stream.readInt();			this.colorType = stream.readUnsignedByte();			stream.readUnsignedByte(); // skip newline character		} catch (IOException e) {			throw new IIOException("Error reading header", e)		}	}</pre></blockquote><blockquote><a name="997661"><!-- --></a>The actual reading of the image is handled by the <code>read</code> method:<p></blockquote><blockquote><pre>	public BufferedImage read(int imageIndex, ImageReadParam param)		throws IIOException {		readMetadata(); // Stream is positioned at start of image data</pre></blockquote><blockquote><a name="1001114"><!-- --></a><i><b> Handling the ImageReadParam</b></i></blockquote><blockquote><a name="997890"><!-- --></a>The first section of the method is concerned with using a supplied ImageReadParam object to determine what region of the source image is to be read, what sort of subsampling is to be applied, the selection and rearrangement of bands, and the offset in the destination:<p></blockquote><blockquote><pre>			// Compute initial source region, clip against destination later	Rectangle sourceRegion = getSourceRegion(param, width, height);			// Set everything to default values	int sourceXSubsampling = 1;	int sourceYSubsampling = 1;	int[] sourceBands = null;	int[] destinationBands = null;	Point destinationOffset = new Point(0, 0);	// Get values from the ImageReadParam, if any	if (param != null) {		sourceXSubsampling = param.getSourceXSubsampling();		sourceYSubsampling = param.getSourceYSubsampling();		sourceBands = param.getSourceBands();		destinationBands = param.getDestinationBands();		destinationOffset = param.getDestinationOffset();	}</pre></blockquote><blockquote><a name="997982"><!-- --></a>At this point, the region of interest, subsampling, band selection, and destination offset have been initialized. The next step is to create a suitable destination image. The <code>ImageReader.getDestination</code> method will return any image that was specified using <code>ImageReadParam.setDestination</code>, or else will create a suitable destination image using a supplied <code>ImageTypeSpecifier</code>, in this case determined by calling <code>getImageTypes(0)</code>:<p></blockquote><blockquote><pre>	// Get the specified detination image or create a new one	BufferedImage dst = getDestination(param,	                                   getImageTypes(0),	                                   width, height);	// Enure band settings from param are compatible with images	int inputBands = (colorType == COLOR_TYPE_RGB) ? 3 : 1;	checkReadParamBandSettings(param, inputBands,	                           dst.getSampleModel().getNumBands());</pre></blockquote><blockquote><a name="998232"><!-- --></a>To reduce the amount of code we have to write, we create a <code>Raster</code> to hold a row&#39;s worth of data, and copy the pixels from that <code>Raster</code> into the actual image. In this way, band selection and the details of pixel formatting are taken care of, at the expense of an additional copy.<p></blockquote><blockquote><pre>	int[] bandOffsets = new int[inputBands];	for (int i = 0; i &lt; inputBands; i++) {		bandOffsets[i] = i;	}	int bytesPerRow = width*inputBands;	DataBufferByte rowDB = new DataBufferByte(bytesPerRow);	WritableRaster rowRas =		Raster.createInterleavedRaster(rowDB,		                               width, 1, bytesPerRow,		                               inputBands, bandOffsets,		                               new Point(0, 0));	byte[] rowBuf = rowDB.getData();	// Create an int[] that can a single pixel	int[] pixel = rowRas.getPixel(0, 0, (int[])null);</pre></blockquote><blockquote><a name="998285"><!-- --></a>Now we have a byte array, <code>rowBuf</code>, which can be filled in from the input data, and which is also the source of pixel data for the <code>Raster</code> <code>rowRaster</code>. We extract the (single) tile of the destination image, and determine its extent. Then we create child rasters of both the source and destination that select and order their bands according to the settings previously extracted from the <code>ImageReadParam</code>:	                               <p></blockquote><blockquote><pre>			WritableRaster imRas = dst.getWritableTile(0, 0);	int dstMinX = imRas.getMinX();	int dstMaxX = dstMinX + imRas.getWidth() - 1;	int dstMinY = imRas.getMinY();	int dstMaxY = dstMinY + imRas.getHeight() - 1;	// Create a child raster exposing only the desired source bands	if (sourceBands != null) {		rowRas = rowRas.createWritableChild(0, 0,		                                    width, 1,		                                    0, 0,		                                    sourceBands);	}	// Create a child raster exposing only the desired dest bands	if (destinationBands != null) {		imRas = imRas.createWritableChild(0, 0,		                                  imRas.getWidth(),		                                  imRas.getHeight(),		                                  0, 0,		                                  destinationBands);	}</pre></blockquote><blockquote><a name="1001111"><!-- --></a><i><b> Reading the Pixel Data</b></i></blockquote><blockquote><a name="997817"><!-- --></a>Now we are ready to begin read pixel data from the image. We will read whole rows, and perform subsampling and destination clipping as we proceed. The horizontal clipping is complicated by the need to take subsampling into account. Here we perform per-pixel clipping; a more sophisticated reader could perform horizontal clipping once:<p></blockquote><blockquote><pre>	for (int srcY = 0; srcY &lt; height; srcY++) {		// Read the row		try {			stream.readFully(rowBuf);		} catch (IOException e) {			throw new IIOException("Error reading line " + srcY, e);		}					// Reject rows that lie outside the source region,		// or which aren&#39;t part of the subsampling		if ((srcY &lt; sourceRegion.y) ||		    (srcY &gt;= sourceRegion.y + sourceRegion.height) ||		    (((srcY - sourceRegion.y) %		      sourceYSubsampling) != 0)) {			continue;		}		// Determine where the row will go in the destination		int dstY = destinationOffset.y +			(srcY - sourceRegion.y)/sourceYSubsampling;		if (dstY &lt; dstMinY) {			continue; // The row is above imRas		}		if (dstY &gt; dstMaxY) {			break; // We&#39;re done with the image		}		// Copy each (subsampled) source pixel into imRas		for (int srcX = sourceRegion.x;		     srcX &lt; sourceRegion.x + sourceRegion.width;		     srcX++) {			if (((srcX - sourceRegion.x) % sourceXSubsampling) != 0) {				continue;			}			int dstX = destinationOffset.x +				(srcX - sourceRegion.x)/sourceXSubsampling;			if (dstX &lt; dstMinX) {				continue;  // The pixel is to the left of imRas			}			if (dstX &gt; dstMaxX) {				break; // We&#39;re done with the row			}			// Copy the pixel, sub-banding is done automatically			rowRas.getPixel(srcX, 0, pixel);			imRas.setPixel(dstX, dstY, pixel);		}	}	return dst;</pre></blockquote><blockquote><a name="998552"><!-- --></a>For performance, the case where <code>sourceXSubsampling</code> is equal to 1 may be broken out separately, since it is possible to copy multiple pixels at once:<p></blockquote><blockquote><pre>	// Create an int[] that can hold a row&#39;s worth of pixels	int[] pixels = rowRas.getPixels(0, 0, width, 1, (int[])null);	// Clip against the left and right edges of the destination image	int srcMinX =		Math.max(sourceRegion.x,                     dstMinX - destinationOffset.x + sourceRegion.x);      int srcMaxX =		Math.min(sourceRegion.x + sourceRegion.width - 1,		         dstMaxX - destinationOffset.x + sourceRegion.x);	int dstX = destinationOffset.x + (srcMinX - sourceRegion.x);	int w = srcMaxX - srcMinX + 1;	rowRas.getPixels(srcMinX, 0, w, 1, pixels);	imRas.setPixels(dstX, dstY, w, 1, pixels);                    </pre></blockquote><blockquote><a name="998652"><!-- --></a>There are several additional features that readers should implement, namely informing listeners of the progress of the read, and allowing the read process to be aborted from another thread.<p></blockquote><blockquote><a name="1001104"><!-- --></a><i><b> Listeners</b></i></blockquote><blockquote><a name="1001103"><!-- --></a>There are three types of listeners that may be attached to a reader: IIOReadProgressListener, IIOReadUpdateListener, and IIOReadWarningListener. Any number of each type may be attached to a reader by means of various add and remove methods that are implemented in the ImageReader superclass. ImageReader also contains various process methods that broadcast information to all of the attached listeners of a given type. For example, when the image read begins, the method processImageStarted(imageIndex) should be called to inform all attached IIOReadProgressListeners of the event.<p><a name="1001230"><!-- --></a>A reader plug-in is normally responsible for calling processImageStarted and processImageComplete at the beginning and end of its read method, respectively. processImageProgress should be called at least every few scanlines with an estimate of the percentage completion of the read. It is important that this percentage never decrease during the read of a single image. If the reader supports thumbnails, the corresponsing thumbnail progress methods should be called as well. The processSequenceStarted and processSequenceComplete methods of IIOReadProgressListener only need to be called if the plug-in overrides the superclass implementation of readAll.<p><a name="1001240"><!-- --></a>More advanced readers that process incoming data in multiple passes may choose to support IIOReadUpdateListeners, which receive more detauled information about which pixels have been read so far. Applications may use this information to perform selective updates of an on-screen image, for example, or to re-encode image data in a streaming fashion.<p></blockquote><blockquote><a name="1001159"><!-- --></a><i><b> Aborting the Read Process</b></i></blockquote><blockquote><a name="1001251"><!-- --></a>While one thread performs an image read, another thread may call the reader&#39;s abort method asynchronously. The reading thread should poll the reader&#39;s status periodically using the abortRequested method, and attempt to cut the decoding short. The partially decoded image should still be returned, although the reader need not make any guarantees about its contents. For example, it could contain compressed or encrypted data in its DataBuffer that does not make sense visually.<p></blockquote><blockquote><a name="1001252"><!-- --></a><i><b> IIOReadProgressListener Example</b></i></blockquote><blockquote><a name="1001142"><!-- --></a>A typical set of IIOReadProgressListener calls might look like this:<p><a name="1001143"><!-- --></a><p></blockquote><blockquote><pre>public BufferedImage read(int imageIndex, ImageReadParam param)	throws IOException {	// Clear any previous abort request	boolean aborted = false;	clearAbortRequested();	// Inform IIOReadProgressListeners of the start of the image	processImageStarted(imageIndex);	// Compute xMin, yMin, xSkip, ySkip from the ImageReadParam	// ...	// Create a suitable image	BufferedImage theImage = new BufferedImage(...);	// Compute factors for use in reporting percentages	int pixelsPerRow = (width - xMin + xSkip - 1)/xSkip;	int rows = (height - yMin + ySkip - 1)/ySkip;	long pixelsDecoded = 0L;	long totalPixels = rows*pixelsPerRow;	for (int y = yMin; y &lt; height; y += yskip) {		// Decode a (subsampled) scanline of the image		// ...		// Update the percentage estimate		// This may be done only every few rows if desired		pixelsDecoded += pixelsPerRow;		processImageProgress(100.0F*pixelsDecoded/totalPixels);		// Check for an asynchronous abort request		if (abortRequested()) {			aborted = true;			break;		}	}	// Handle the end of decoding	if (aborted) {		processImageAborted();

⌨️ 快捷键说明

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