Package com.keypoint

Class PngEncoder


  • public class PngEncoder
    extends java.lang.Object
    PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file. The Image is presumed to use the DirectColorModel.

    Thanks to Jay Denny at KeyPoint Software http://www.keypoint.com/ who let me develop this code on company time.

    You may contact me with (probably very-much-needed) improvements, comments, and bug fixes at:

    david@catcode.com

    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.

    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.

    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. A copy of the GNU LGPL may be found at http://www.gnu.org/copyleft/lesser.html

    Version:
    1.5, 19 Oct 2003 CHANGES: -------- 19-Nov-2002 : CODING STYLE CHANGES ONLY (by David Gilbert for Object Refinery Limited); 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 15-Aug-2008 : Added scrunch.end() in writeImageData() method - see JFreeChart bug report 2037930 (David Gilbert);
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected int bytePos
      The byte position.
      protected int bytesPerPixel
      The bytes-per-pixel.
      protected int compressionLevel
      The compression level (1 = best speed, 9 = best compression, 0 = no compression).
      protected java.util.zip.CRC32 crc
      CRC.
      protected long crcValue
      The CRC value.
      static boolean ENCODE_ALPHA
      Constant specifying that alpha channel should be encoded.
      protected boolean encodeAlpha
      Encode alpha?
      protected int filter
      The filter type.
      static int FILTER_LAST
      Constants for filter (LAST).
      static int FILTER_NONE
      Constants for filter (NONE).
      static int FILTER_SUB
      Constants for filter (SUB).
      static int FILTER_UP
      Constants for filter (UP).
      protected int height
      The height.
      protected static byte[] IDAT
      IDAT tag.
      protected static byte[] IEND
      IEND tag.
      protected static byte[] IHDR
      IHDR tag.
      protected java.awt.Image image
      The image.
      private static float INCH_IN_METER_UNIT
      Used for conversion of DPI to Pixels per Meter.
      protected byte[] leftBytes
      The left bytes.
      protected int maxPos
      The maximum position.
      static boolean NO_ALPHA
      Constant specifying that alpha channel should not be encoded.
      protected static byte[] PHYS
      PHYS tag.
      protected byte[] pngBytes
      The png bytes.
      protected byte[] priorRow
      The prior row.
      protected int width
      The width.
      private int xDpi
      The physical pixel dimension : number of pixels per inch on the X axis.
      private int yDpi
      The physical pixel dimension : number of pixels per inch on the Y axis.
    • Constructor Summary

      Constructors 
      Constructor Description
      PngEncoder()
      Class constructor.
      PngEncoder​(java.awt.Image image)
      Class constructor specifying Image to encode, with no alpha channel encoding.
      PngEncoder​(java.awt.Image image, boolean encodeAlpha)
      Class constructor specifying Image to encode, and whether to encode alpha.
      PngEncoder​(java.awt.Image image, boolean encodeAlpha, int whichFilter)
      Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
      PngEncoder​(java.awt.Image image, boolean encodeAlpha, int whichFilter, int compLevel)
      Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void filterSub​(byte[] pixels, int startPos, int width)
      Perform "sub" filtering on the given row.
      protected void filterUp​(byte[] pixels, int startPos, int width)
      Perform "up" filtering on the given row.
      int getCompressionLevel()
      Retrieve compression level.
      boolean getEncodeAlpha()
      Retrieve alpha encoding status.
      int getFilter()
      Retrieve filtering scheme.
      java.awt.Image getImage()
      Returns the image to be encoded.
      int getXDpi()
      Get the DPI for the X axis.
      int getYDpi()
      Get the DPI for the Y axis.
      byte[] pngEncode()
      Creates an array of bytes that is the PNG equivalent of the current image.
      byte[] pngEncode​(boolean encodeAlpha)
      Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
      protected byte[] resizeByteArray​(byte[] array, int newLength)
      Increase or decrease the length of a byte array.
      void setCompressionLevel​(int level)
      Set the compression level to use.
      void setDpi​(int xDpi, int yDpi)
      Set the DPI resolution.
      void setEncodeAlpha​(boolean encodeAlpha)
      Set the alpha encoding on or off.
      void setFilter​(int whichFilter)
      Set the filter to use.
      void setImage​(java.awt.Image image)
      Set the image to be encoded.
      void setXDpi​(int xDpi)
      Set the DPI for the X axis.
      void setYDpi​(int yDpi)
      Set the DPI for the Y axis.
      protected int writeByte​(int b, int offset)
      Write a single byte into the pngBytes array at a given position.
      protected int writeBytes​(byte[] data, int offset)
      Write an array of bytes into the pngBytes array.
      protected int writeBytes​(byte[] data, int nBytes, int offset)
      Write an array of bytes into the pngBytes array, specifying number of bytes to write.
      protected void writeEnd()
      Write a PNG "IEND" chunk into the pngBytes array.
      protected void writeHeader()
      Write a PNG "IHDR" chunk into the pngBytes array.
      protected boolean writeImageData()
      Write the image data into the pngBytes array.
      protected int writeInt2​(int n, int offset)
      Write a two-byte integer into the pngBytes array at a given position.
      protected int writeInt4​(int n, int offset)
      Write a four-byte integer into the pngBytes array at a given position.
      protected void writeResolution()
      Write a PNG "pHYs" chunk into the pngBytes array.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • ENCODE_ALPHA

        public static final boolean ENCODE_ALPHA
        Constant specifying that alpha channel should be encoded.
        See Also:
        Constant Field Values
      • NO_ALPHA

        public static final boolean NO_ALPHA
        Constant specifying that alpha channel should not be encoded.
        See Also:
        Constant Field Values
      • FILTER_NONE

        public static final int FILTER_NONE
        Constants for filter (NONE).
        See Also:
        Constant Field Values
      • FILTER_SUB

        public static final int FILTER_SUB
        Constants for filter (SUB).
        See Also:
        Constant Field Values
      • FILTER_UP

        public static final int FILTER_UP
        Constants for filter (UP).
        See Also:
        Constant Field Values
      • FILTER_LAST

        public static final int FILTER_LAST
        Constants for filter (LAST).
        See Also:
        Constant Field Values
      • IHDR

        protected static final byte[] IHDR
        IHDR tag.
      • IDAT

        protected static final byte[] IDAT
        IDAT tag.
      • IEND

        protected static final byte[] IEND
        IEND tag.
      • PHYS

        protected static final byte[] PHYS
        PHYS tag.
      • pngBytes

        protected byte[] pngBytes
        The png bytes.
      • priorRow

        protected byte[] priorRow
        The prior row.
      • leftBytes

        protected byte[] leftBytes
        The left bytes.
      • image

        protected java.awt.Image image
        The image.
      • width

        protected int width
        The width.
      • height

        protected int height
        The height.
      • bytePos

        protected int bytePos
        The byte position.
      • maxPos

        protected int maxPos
        The maximum position.
      • crc

        protected java.util.zip.CRC32 crc
        CRC.
      • crcValue

        protected long crcValue
        The CRC value.
      • encodeAlpha

        protected boolean encodeAlpha
        Encode alpha?
      • filter

        protected int filter
        The filter type.
      • bytesPerPixel

        protected int bytesPerPixel
        The bytes-per-pixel.
      • xDpi

        private int xDpi
        The physical pixel dimension : number of pixels per inch on the X axis.
      • yDpi

        private int yDpi
        The physical pixel dimension : number of pixels per inch on the Y axis.
      • INCH_IN_METER_UNIT

        private static float INCH_IN_METER_UNIT
        Used for conversion of DPI to Pixels per Meter.
      • compressionLevel

        protected int compressionLevel
        The compression level (1 = best speed, 9 = best compression, 0 = no compression).
    • Constructor Detail

      • PngEncoder

        public PngEncoder()
        Class constructor.
      • PngEncoder

        public PngEncoder​(java.awt.Image image)
        Class constructor specifying Image to encode, with no alpha channel encoding.
        Parameters:
        image - A Java Image object which uses the DirectColorModel
        See Also:
        Image
      • PngEncoder

        public PngEncoder​(java.awt.Image image,
                          boolean encodeAlpha)
        Class constructor specifying Image to encode, and whether to encode alpha.
        Parameters:
        image - A Java Image object which uses the DirectColorModel
        encodeAlpha - Encode the alpha channel? false=no; true=yes
        See Also:
        Image
      • PngEncoder

        public PngEncoder​(java.awt.Image image,
                          boolean encodeAlpha,
                          int whichFilter)
        Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
        Parameters:
        image - A Java Image object which uses the DirectColorModel
        encodeAlpha - Encode the alpha channel? false=no; true=yes
        whichFilter - 0=none, 1=sub, 2=up
        See Also:
        Image
      • PngEncoder

        public PngEncoder​(java.awt.Image image,
                          boolean encodeAlpha,
                          int whichFilter,
                          int compLevel)
        Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.
        Parameters:
        image - A Java Image object
        encodeAlpha - Encode the alpha channel? false=no; true=yes
        whichFilter - 0=none, 1=sub, 2=up
        compLevel - 0..9 (1 = best speed, 9 = best compression, 0 = no compression)
        See Also:
        Image
    • Method Detail

      • setImage

        public void setImage​(java.awt.Image image)
        Set the image to be encoded.
        Parameters:
        image - A Java Image object which uses the DirectColorModel
        See Also:
        Image, DirectColorModel
      • getImage

        public java.awt.Image getImage()
        Returns the image to be encoded.
        Returns:
        The image.
      • pngEncode

        public byte[] pngEncode​(boolean encodeAlpha)
        Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
        Parameters:
        encodeAlpha - boolean false=no alpha, true=encode alpha
        Returns:
        an array of bytes, or null if there was a problem
      • pngEncode

        public byte[] pngEncode()
        Creates an array of bytes that is the PNG equivalent of the current image. Alpha encoding is determined by its setting in the constructor.
        Returns:
        an array of bytes, or null if there was a problem
      • setEncodeAlpha

        public void setEncodeAlpha​(boolean encodeAlpha)
        Set the alpha encoding on or off.
        Parameters:
        encodeAlpha - false=no, true=yes
      • getEncodeAlpha

        public boolean getEncodeAlpha()
        Retrieve alpha encoding status.
        Returns:
        boolean false=no, true=yes
      • setFilter

        public void setFilter​(int whichFilter)
        Set the filter to use.
        Parameters:
        whichFilter - from constant list
      • getFilter

        public int getFilter()
        Retrieve filtering scheme.
        Returns:
        int (see constant list)
      • setCompressionLevel

        public void setCompressionLevel​(int level)
        Set the compression level to use.
        Parameters:
        level - the compression level (1 = best speed, 9 = best compression, 0 = no compression)
      • getCompressionLevel

        public int getCompressionLevel()
        Retrieve compression level.
        Returns:
        int (1 = best speed, 9 = best compression, 0 = no compression)
      • resizeByteArray

        protected byte[] resizeByteArray​(byte[] array,
                                         int newLength)
        Increase or decrease the length of a byte array.
        Parameters:
        array - The original array.
        newLength - The length you wish the new array to have.
        Returns:
        Array of newly desired length. If shorter than the original, the trailing elements are truncated.
      • writeBytes

        protected int writeBytes​(byte[] data,
                                 int offset)
        Write an array of bytes into the pngBytes array. Note: This routine has the side effect of updating maxPos, the largest element written in the array. The array is resized by 1000 bytes or the length of the data to be written, whichever is larger.
        Parameters:
        data - The data to be written into pngBytes.
        offset - The starting point to write to.
        Returns:
        The next place to be written to in the pngBytes array.
      • writeBytes

        protected int writeBytes​(byte[] data,
                                 int nBytes,
                                 int offset)
        Write an array of bytes into the pngBytes array, specifying number of bytes to write. Note: This routine has the side effect of updating maxPos, the largest element written in the array. The array is resized by 1000 bytes or the length of the data to be written, whichever is larger.
        Parameters:
        data - The data to be written into pngBytes.
        nBytes - The number of bytes to be written.
        offset - The starting point to write to.
        Returns:
        The next place to be written to in the pngBytes array.
      • writeInt2

        protected int writeInt2​(int n,
                                int offset)
        Write a two-byte integer into the pngBytes array at a given position.
        Parameters:
        n - The integer to be written into pngBytes.
        offset - The starting point to write to.
        Returns:
        The next place to be written to in the pngBytes array.
      • writeInt4

        protected int writeInt4​(int n,
                                int offset)
        Write a four-byte integer into the pngBytes array at a given position.
        Parameters:
        n - The integer to be written into pngBytes.
        offset - The starting point to write to.
        Returns:
        The next place to be written to in the pngBytes array.
      • writeByte

        protected int writeByte​(int b,
                                int offset)
        Write a single byte into the pngBytes array at a given position.
        Parameters:
        b - The integer to be written into pngBytes.
        offset - The starting point to write to.
        Returns:
        The next place to be written to in the pngBytes array.
      • writeHeader

        protected void writeHeader()
        Write a PNG "IHDR" chunk into the pngBytes array.
      • filterSub

        protected void filterSub​(byte[] pixels,
                                 int startPos,
                                 int width)
        Perform "sub" filtering on the given row. Uses temporary array leftBytes to store the original values of the previous pixels. The array is 16 bytes long, which will easily hold two-byte samples plus two-byte alpha.
        Parameters:
        pixels - The array holding the scan lines being built
        startPos - Starting position within pixels of bytes to be filtered.
        width - Width of a scanline in pixels.
      • filterUp

        protected void filterUp​(byte[] pixels,
                                int startPos,
                                int width)
        Perform "up" filtering on the given row. Side effect: refills the prior row with current row
        Parameters:
        pixels - The array holding the scan lines being built
        startPos - Starting position within pixels of bytes to be filtered.
        width - Width of a scanline in pixels.
      • writeImageData

        protected boolean writeImageData()
        Write the image data into the pngBytes array. This will write one or more PNG "IDAT" chunks. In order to conserve memory, this method grabs as many rows as will fit into 32K bytes, or the whole image; whichever is less.
        Returns:
        true if no errors; false if error grabbing pixels
      • writeEnd

        protected void writeEnd()
        Write a PNG "IEND" chunk into the pngBytes array.
      • setXDpi

        public void setXDpi​(int xDpi)
        Set the DPI for the X axis.
        Parameters:
        xDpi - The number of dots per inch
      • getXDpi

        public int getXDpi()
        Get the DPI for the X axis.
        Returns:
        The number of dots per inch
      • setYDpi

        public void setYDpi​(int yDpi)
        Set the DPI for the Y axis.
        Parameters:
        yDpi - The number of dots per inch
      • getYDpi

        public int getYDpi()
        Get the DPI for the Y axis.
        Returns:
        The number of dots per inch
      • setDpi

        public void setDpi​(int xDpi,
                           int yDpi)
        Set the DPI resolution.
        Parameters:
        xDpi - The number of dots per inch for the X axis.
        yDpi - The number of dots per inch for the Y axis.
      • writeResolution

        protected void writeResolution()
        Write a PNG "pHYs" chunk into the pngBytes array.