My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Overview  

Featured
Updated Apr 14, 2012 by hgonza...@gmail.com

PNGJ - PNG Java library

PNGJ is a library to read/write PNG images. It's fully written in Java, without any dependencies on javax.io, AWT or any third party libraries.

It provides a simple API for progressive (sequential line-oriented) reading and writing. It's specially suitable for huge images, which one does not want to load fully in memory, eg. (as a BufferedImage).

It supports (as of June 2011) all PNG spec color models and bitdepths:

True color: 8-16 bpp, with and without alpha channel (RGB/RGBA)
Grayscale: 1-2-4-8-16 bpp, with and without alpha channel
Indexed: palette with 1-2-4-8 bits

It does not support interlaced images.

It has been tested (read and write) against the full standard PNG test suite - except for the interlaced images.

A quick example of use: the sample code below reads a PNG image file (true colour RGB/RGBA, 8 or 16 bpp), decreases the red channel value by 50% and writes it into another PNG file.

 public static void decreaseRed(String origFilename, String destFilename) {
        PngReader pngr = FileHelper.createPngReader(new File(origFilename));
        PngWriter pngw = FileHelper.createPngWriter(new File(destFilename), pngr.imgInfo, true);
        System.out.println(pngr.toString());
        // this can copy some metadata from reader
        pngw.copyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
        int channels = pngr.imgInfo.channels;
        if (channels < 3)
            throw new RuntimeException("This method is for RGB/RGBA images");
        for (int row = 0; row < pngr.imgInfo.rows; row++) {
            ImageLine l1 = pngr.readRow(row);
            for (int j = 0; j < pngr.imgInfo.cols; j++)
                l1.scanline[j * channels] /= 2;
            pngw.writeRow(l1, row);
        }
        // just in case some new metadata has been read after the image
        pngw.copyChunksLast(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
        pngw.end();
    }

The following sample code generates an RGB8 (orange-ish gradient) image to an OutputStream. Because only an image line is allocated, this would allow the creation of very large images with low memory usage.

        ImageInfo imi = new ImageInfo(cols, rows, 8, false); // 8 bits per channel, no alpha 
        // open image for writing to a output stream 
        PngWriter png = new PngWriter(outputStream, imi ); 
        // add some optional metadata (chunks)
        png.getMetadata().setDpi(100.0);
        png.getMetadata().setTimeNow(); 
        png.getMetadata().setText(PngChunkTextVar.KEY_Title, "just a text image");
        png.getMetadata().setText("my key", "my text");
        ImageLine iline = new ImageLine(imi);
        for (int col = 0; col < imi.cols; col++) { // this line will be written to all rows  
            int r = 255;
            int g = 127;
            int b = 255 * col / imi.cols;
            ImageLineHelper.setPixelRGB8(iline, col, r, g, b); // orange-ish gradient
        }
        for (int row = 0; row < png.imgInfo.rows; row++) {
            png.writeRow(iline, row);
        }
        png.end();

Questions? Read the FAQ or the Javadocs

Another suggested reading: samples included in the test package, classes starting with Sample*.


Sign in to add a comment
Powered by Google Project Hosting