📄 pngencoderb.java
字号:
package com.keypoint;import java.awt.Image;import java.awt.image.BufferedImage;import java.awt.image.DataBuffer;import java.awt.image.IndexColorModel;import java.awt.image.ImageObserver;import java.awt.image.PixelGrabber;import java.awt.image.WritableRaster;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.zip.CRC32;import java.util.zip.Deflater;import java.util.zip.DeflaterOutputStream;/** * PngEncoderB takes a Java BufferedImage object and creates a byte string which can be saved as a PNG file. * The encoder will accept BufferedImages with eight-bit samples * or 4-byte ARGB samples. * * <p>There is also code to handle 4-byte samples returned as * one int per pixel, but that has not been tested.</p> * * <p>Thanks to Jay Denny at KeyPoint Software * <code>http://www.keypoint.com/</code> * who let me develop this code on company time.</p> * * <p>You may contact me with (probably very-much-needed) improvements, * comments, and bug fixes at:</p> * * <p><code>david@catcode.com</code></p> * * <p>This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version.<p> * * <p>This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details.</p> * * <p>You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * A copy of the GNU LGPL may be found at * <code>http://www.gnu.org/copyleft/lesser.html</code></p> * * @author J. David Eisenberg * @version 1.5, 19 Oct 2003 * * CHANGES: * -------- * 19-Sep-2003 : Fix for platforms using EBCDIC (contributed by Paulo Soares); * 19-Oct-2003 : Change private fields to protected fields so that * PngEncoderB can inherit them (JDE) * Fixed bug with calculation of nRows * Added modifications for unsigned short images * (contributed by Christian at xpogen.com) */public class PngEncoderB extends PngEncoder { /** PLTE tag. */ private static final byte PLTE[] = { 80, 76, 84, 69 }; protected BufferedImage image; protected WritableRaster wRaster; protected int tType; /** * Class constructor * */ public PngEncoderB() { this( null, false, FILTER_NONE, 0 ); } /** * Class constructor specifying BufferedImage to encode, with no alpha channel encoding. * * @param image A Java BufferedImage object */ public PngEncoderB( BufferedImage image ) { this(image, false, FILTER_NONE, 0); } /** * Class constructor specifying BufferedImage to encode, and whether to encode alpha. * * @param image A Java BufferedImage object * @param encodeAlpha Encode the alpha channel? false=no; true=yes */ public PngEncoderB( BufferedImage image, boolean encodeAlpha ) { this( image, encodeAlpha, FILTER_NONE, 0 ); } /** * Class constructor specifying BufferedImage to encode, whether to encode alpha, and filter to use. * * @param image A Java BufferedImage object * @param encodeAlpha Encode the alpha channel? false=no; true=yes * @param whichFilter 0=none, 1=sub, 2=up */ public PngEncoderB( BufferedImage image, boolean encodeAlpha, int whichFilter ) { this( image, encodeAlpha, whichFilter, 0 ); } /** * Class constructor specifying BufferedImage source to encode, whether to encode alpha, filter to use, and compression level * * @param image A Java BufferedImage object * @param encodeAlpha Encode the alpha channel? false=no; true=yes * @param whichFilter 0=none, 1=sub, 2=up * @param compLevel 0..9 */ public PngEncoderB( BufferedImage image, boolean encodeAlpha, int whichFilter, int compLevel ) { this.image = image; this.encodeAlpha = encodeAlpha; setFilter( whichFilter ); if (compLevel >=0 && compLevel <=9) { this.compressionLevel = compLevel; } } /** * Set the BufferedImage to be encoded * * @param BufferedImage A Java BufferedImage object */ public void setImage( BufferedImage image ) { this.image = image; pngBytes = null; } /** * Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not. * * @param encodeAlpha boolean false=no alpha, true=encode alpha * @return an array of bytes, or null if there was a problem */ public byte[] pngEncode( boolean encodeAlpha ) { byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 }; int i; if (image == null) { System.err.println("pngEncode: image is null; returning null"); return null; } width = image.getWidth( null ); height = image.getHeight( null ); this.image = image; if (!establishStorageInfo()) { System.err.println("pngEncode: cannot establish storage info"); return null; } /* * start with an array that is big enough to hold all the pixels * (plus filter bytes), and an extra 200 bytes for header info */ pngBytes = new byte[((width+1) * height * 3) + 200]; /* * keep track of largest byte written to the array */ maxPos = 0; bytePos = writeBytes( pngIdBytes, 0 ); // hdrPos = bytePos; writeHeader();// dataPos = bytePos; if (writeImageData()) { writeEnd(); pngBytes = resizeByteArray( pngBytes, maxPos ); } else { System.err.println("pngEncode: writeImageData failed => null"); pngBytes = null; } return pngBytes; } /** * Creates an array of bytes that is the PNG equivalent of the current image. * Alpha encoding is determined by its setting in the constructor. * * @return an array of bytes, or null if there was a problem */ public byte[] pngEncode() { return pngEncode( encodeAlpha ); } /** * * Get and set variables that determine how picture is stored. * * Retrieves the writable raster of the buffered image, * as well its transfer type. * * Sets number of output bytes per pixel, and, if only * eight-bit bytes, turns off alpha encoding. * @return true if 1-byte or 4-byte data, false otherwise */ protected boolean establishStorageInfo() { int dataBytes; wRaster = image.getRaster(); dataBytes = wRaster.getNumDataElements(); tType = wRaster.getTransferType(); if (((tType == DataBuffer.TYPE_BYTE ) && (dataBytes == 4)) || ((tType == DataBuffer.TYPE_INT ) && (dataBytes == 1)) || // on Win 2k/ME, tType == 1, dataBytes == 1 ((tType == DataBuffer.TYPE_USHORT) && (dataBytes == 1)) ) { bytesPerPixel = (encodeAlpha) ? 4 : 3; } else if ((tType == DataBuffer.TYPE_BYTE) && (dataBytes == 1)) { bytesPerPixel = 1; encodeAlpha = false; // one-byte samples } else { System.err.println("PNG encoder cannot establish storage info:"); System.err.println(" TransferType == " + tType ); System.err.println(" NumDataElements == " + dataBytes); return false; } return true; } /** * Write a PNG "IHDR" chunk into the pngBytes array. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -