Coder Social home page Coder Social logo

pngj's Introduction

PNGJ: Java library for PNG encoding

PNGJ is a pure Java library for high performance reading and writing of PNG images


Downloads

You can download the latest release from here http://hjg.com.ar/pngj/ or use the Maven Central repository

Main features

  • Very efficient in memory usage and speed
  • Pure Java (8 or greater)
  • Small and self contained. No dependencies on third party libraries, nor even on java.awt.* or javax.imageio.*
  • Runs on Android and GAE (Google App Engine)
  • Allows to read and write progressively, row by row. This means that you can process huge images without needing to load them fully in memory.
  • Reads and writes all PNG color models. Interlaced PNG is supported (though not welcomed) for reading.
  • Full support for metadata handling ("chunks").
  • The format of the pixel data (for read and write) is extensible and efficient (no double copies).
  • Supports asyncronous reading and low level tweaking and extension in the reader.
  • Basic support for APNG reading
  • Open source (Apache licence). Available in Maven Central repository.

What is this for?

This is a relatively low level library, its goal is to code and decode PNG images from/to raw pixels, optimizing memory usage and speed. It does not provide any high-level image processing (eg, resizing, colour conversions), it does not try to abstract the concrete PNG color model (as BufferedImage does, for example). In particular, the default format of the scanlines (as wrapped in ImageLineInt or ImageLineByte) is not abstract, the meaning of the values depends on the image color model and bitdepth.

More documentation

pngj's People

Contributors

leonbloy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pngj's Issues

Different filter types per scanline

According to http://www.libpng.org/pub/png/spec/1.2/PNG-DataRep.html#DR.Filtering it is generally possible to use a different filter type for each individual scanline. Are there plans for supporting this? At the moment the documentation for PngWriter.setFilterType() states that this has to be called just after construction, I guess one could implement it in a way such that it can be altered in between calls to PngWriter.writeRow(). Or maybe this is already working?

PngWriter did not write meta data into output stream.

From [email protected] on March 24, 2014 01:29:29

What steps will reproduce the problem? 1. Create a Png Image using PngWriter like the following (psuedo code)
int side = 80;
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageInfo imageInfo = new ImageInfo(side, side, 8, true); // 8 bits true color RGBA
PngWriter png = new PngWriter(os, imageInfo);

           png.getMetadata().setDpi(300);
           // ... and more setting ..

          //write the png
          png.end();
  1. The image looks good. However, the meta data is not shown. DPI is set to 72 instead of 300.
  2. A quick scan of the code indicate that meta data object is not written to file. What is the expected output? What do you see instead? Write the meta data to the PNG file - for me, the DPI setting is very important (for printing purpose). What version of the product are you using? On what operating system? 2.0.1. on Java / MacOS (testing) / AppEngine (production) Please provide any additional information below.

Original issue: http://code.google.com/p/pngj/issues/detail?id=29

can't find alpha channel

From [email protected] on January 20, 2013 17:06:23

What steps will reproduce the problem? 1.I am trying to decode a png with transparency (attached file) as a byte array.
I download that png with WebClient.DownloadDataAsync() and the data from the result is used like this:

PngReader pngr = new PngReader(new MemoryStream(data));

What is the expected output?
An image with an alpha channel

What do you see instead?
That same image (the RGB channels are ok) without alpha channel:
the number of channels is "3", pngr.Alpha is "false" and pngr.GetMetadata().GetTRNS() is "null". What version of the product are you using? On what operating system? 25ae2a736db5

Attachment: map.png

Original issue: http://code.google.com/p/pngj/issues/detail?id=24

Slow tiling

When testing 2 png with about 200kb each....the tiling sample is slow....is possivel to spedup this routine?

Project is dead?

Just want to confirm that this project is dead. Judging by the number of forks and that nothing happened here for several years it is save to assume that this project is dead.

Any (maintained) alternatives?

Please add a license

Would you mind adding a license?
For instance MIT license or just write in the README "This library is public domain" or something like this.
Without a license, it is not legal to use this library.
Thanks! :-)

PngReaderApng.advanceToFrame(int) throws exception when frame > frameNum

From [email protected] on December 09, 2014 13:46:22

What steps will reproduce the problem? 1.open an APNG with the PngReaderApng
2.call advanceToFrame(1)
3.an exception is thrown: ar.com.hjg.pngj.PngjInputException: this should only be called if waitingForMoreInput

After comparing this function and PngReader.end(), I found that it might forget to call chunkseq.getIdatSet().done();

I modified the feeding loop as follows:
if (chunkseq.getIdatSet() != null&&!chunkseq.getIdatSet().isDone())
chunkseq.getIdatSet().done();
while (frameNum < frame)
if (streamFeeder.feed(chunkseq) <= 0)
break;
and the problem is solved.

I don't know if this solution is correct or optimal though, but hopefully it helped.

I've been looking for a solution to decode an apng file in java for a few days and PNGJ seems the only solution, which is very efficient and elegant in my opinion. Thank you for the hard work :)

Original issue: http://code.google.com/p/pngj/issues/detail?id=33

invalid bitdepth ? how to solve it?

From [email protected] on August 29, 2010 06:46:39

What steps will reproduce the problem? 1. add jars.
2. write a sample to genarate the png image follow the PngCreate class in the source jar.
3. run it. What is the expected output? What do you see instead? ar.com.hjg.pngj.PngjException: invalid bitdepth=5
at ar.com.hjg.pngj.ImageInfo.(ImageInfo.java:93)
at ar.com.hjg.pngj.ImageInfo.(ImageInfo.java:50)
at cn.xiazhengxin.blog.util.GenPng.Create(GenPng.java:22)
……………… What version of the product are you using? On what operating system? JDK 6u21 on ubuntu 10.04 Please provide any additional information below. none.

Original issue: http://code.google.com/p/pngj/issues/detail?id=1

Use of BufferedInputStream in FileHelper.openFileForReading

From [email protected] on January 16, 2013 23:27:31

In FileHelper.openFileForReading, a FileInputStream is wrapped by a BufferedInputStream. I found that taking the BufferedInputStream off and returning a FileInputStream directly had no change in performance, and reduced memory footprint a small amount due to the internal buffered in the BufferedInputStream. I'm wondering if this wrapper is necessary?

Original issue: http://code.google.com/p/pngj/issues/detail?id=23

Investigate filtering strategies

From [email protected] on September 06, 2012 11:49:39

Perhaps We could make better with the filtering choosing strategy. Some ideas:

  1. GIve more felxibility to the user for setting heuristic parameters. Perhaps even the strategy itself (as a custom objet)
  2. Investigate libpng in this regard (see png_write_filtered_row in pngwutil.c ) Is it useful to include some "inercy" in the filter selection?
  3. What about using entropy instead of sum of errors?
  4. What about encoding simultaneously with all 4 filters to different streams and choosing one of them every N rows (sounds crazy, but...)?

Original issue: http://code.google.com/p/pngj/issues/detail?id=16

Multiple reads for metadata of a PNG causes a null pointer on Android 2.2.2

From [email protected] on October 15, 2013 02:16:41

What steps will reproduce the problem? 1.Create a PNG with pngj
2.Read the file once, skipping all bytes to just get metadata
3.Do it again in the same Thread and you'll get a null pointer exception What is the expected output? What do you see instead? I expect the second read not to throw a null pointer. A null pointer. What version of the product are you using? On what operating system? pngj version 2.0.0 on Windows 7 & Android 2.2.2 Please provide any additional information below. I'd like to use this library for an Android application that I'm creating, however I can't get passed a null pointer that it's throwing.

If you create a PNG with the library, and then try and retrieve the metadata from it twice in a row in a single Thread on Android you will get the following null pointer (works fine on Windows);

ar.com.hjg.pngj.PngjException: java.lang.NullPointerException
at ar.com.hjg.pngj.chunks.ChunkHelper.compressBytes(ChunkHelper.java:219)
at ar.com.hjg.pngj.chunks.PngChunkZTXT.parseFromRaw(PngChunkZTXT.java:57)
at ar.com.hjg.pngj.chunks.ChunkFactory.createChunk(ChunkFactory.java:32)
at ar.com.hjg.pngj.ChunkSeqReaderPng.postProcessChunk(ChunkSeqReaderPng.java:148)
at ar.com.hjg.pngj.ChunkSeqReader$2.chunkDone(ChunkSeqReader.java:178)
at ar.com.hjg.pngj.ChunkReader.feedBytes(ChunkReader.java:134)
at ar.com.hjg.pngj.ChunkSeqReader.consume(ChunkSeqReader.java:99)
at ar.com.hjg.pngj.ChunkSeqReaderPng.consume(ChunkSeqReaderPng.java:184)
at ar.com.hjg.pngj.BufferedStreamFeeder.feed(BufferedStreamFeeder.java:60)
at ar.com.hjg.pngj.BufferedStreamFeeder.feed(BufferedStreamFeeder.java:46)
at ar.com.hjg.pngj.PngReader.end(PngReader.java:441)
at ar.com.hjg.pngj.PngReader.readSkippingAllRows(PngReader.java:367)

Here is the code that is using the pngj library;

String metadata = null;
pngr.setShouldCloseStream(false);
pngr.getChunkseq().setIncludeNonBufferedChunks(true);
pngr.readSkippingAllRows(); // reads only metadata
for(PngChunk c : pngr.getChunksList().getChunks())
{
if (!ChunkHelper.isText(c))
continue;
PngChunkTextVar ct = (PngChunkTextVar) c;
String key = ct.getKey();
if(PngChunkTextVar.KEY_Comment.equalsIgnoreCase(key))
{
metadata = ct.getVal();
break;
}
}

...

pngr.end();
pngr.close();

Executing the above, twice, produces the null pointer. I have tried a hundred permutations of the above to no avail.

What's weird is that the error is coming from a class that is attempting to compress data even though I'm not writing anything. The code above only reads the file. Theoretically there should be no reason for the code to take that execution path.

In any event, maybe you'll be able to figure it out.

thanks

Original issue: http://code.google.com/p/pngj/issues/detail?id=26

Memory efficiency in FilterType[] enum

From [email protected] on January 16, 2013 01:22:46

I am working on an application that loads many PNG images very rapidly and I am trying to decrease memory allocations to meet garbage collector performance constraints in other parts of the application. As such, I am planning to switch from ImageIO.read(..) to pngj as a more efficient alternative.

I have been profiling pngj under visualvm with a test application that reads the same png file over and over in an infinite loop. I noticed an unexpected source of unexpected memory allocations in ar.com.hjg.pngj.FilterType. In particular, the use of values() in getByVal(int) creates an extraneous instance of FilterType[]. I made a tiny change to store the result of values() in a static variable that makes the extra allocations go away.

My updated FilterType class is attached.

Attachment: FilterType.java

Original issue: http://code.google.com/p/pngj/issues/detail?id=21

Compatibility with BufferedImage

From [email protected] on May 15, 2013 03:07:59

I'm rewriting critical part of image processing from BufferedImage to pngj. However I prefer to leave BufferedImage in some image-processing parts of program.

I have the following flow:

  1. Load bufferedimage from bytes
  2. Copy line-by-line bytes from BufferedImage to .png file with alpha using pngj.

{{{
int[] array = new int[3];
bufferedImage.getRaster().getPixel(x, y, array);

    iline.scanline[j++] = array[0]; // R
    iline.scanline[j++] = array[1]; // G
    iline.scanline[j++] = array[2]; // B
    iline.scanline[j++] = 0xFF; // alpha

}}}

In the example above a have sample .jpg 24-bit image.
3. Check result .png is the same as input .jpg
4. Read result image with BufferedImage (for further processing).

Expected:
At step 4: The BufferedImage type is 2 (TYPE_INT_ARGB)

The actual result:
Depends on platform.
On Windows 7 (64bit): type is 0 (TYPE_CUSTOM)
On Linux (Ubuntu 12.04 64bit): type is 6 (TYPE_4BYTE_ABGR)

So I have several questions in here:

  1. How I could archive cross-platform compatibility? Is it something related to BufferedImage/awt native code?
  2. How I could specify for pngj the desired color order, ie. ARGB instead of RGBA?
  3. Why do I receive 4BYTE type in Linux instead of INT?

Original issue: http://code.google.com/p/pngj/issues/detail?id=25

java.lang.ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
    at ar.com.hjg.pngj.PngHelperInternal.readInt2fromBytes(PngHelperInternal.java:101)
    at ar.com.hjg.pngj.chunks.PngChunkTRNS.parseFromRaw(PngChunkTRNS.java:65)
    at ar.com.hjg.pngj.chunks.ChunkFactory.createChunk(ChunkFactory.java:32)
    at ar.com.hjg.pngj.ChunkSeqReaderPng.postProcessChunk(ChunkSeqReaderPng.java:167)
    at ar.com.hjg.pngj.PngReaderApng$1.postProcessChunk(PngReaderApng.java:169)
    at ar.com.hjg.pngj.ChunkSeqReader$2.chunkDone(ChunkSeqReader.java:242)
    at ar.com.hjg.pngj.ChunkReader.consume(ChunkReader.java:153)
    at ar.com.hjg.pngj.ChunkSeqReader.consume(ChunkSeqReader.java:115)
    at ar.com.hjg.pngj.ChunkSeqReaderPng.consume(ChunkSeqReaderPng.java:200)
    at ar.com.hjg.pngj.BufferedStreamFeeder.feed(BufferedStreamFeeder.java:63)
    at ar.com.hjg.pngj.BufferedStreamFeeder.feed(BufferedStreamFeeder.java:45)
    at ar.com.hjg.pngj.PngReader.readFirstChunks(PngReader.java:211)
    at ar.com.hjg.pngj.PngReader.end(PngReader.java:524)
    at ar.com.hjg.pngj.PngReaderApng.end(PngReaderApng.java:202)
    at com.laoyuegou.apng.utils.ApngDecode.readApngInformation(ApngDecode.java:285)

ChunksList cannot be cast to ChunksListForWrite

When I simply try to write something to metadata, ClassCastException is thrown.

My code:
PngReader pngReader = new PngReader(new File("path to png image"));
pngReader.getMetadata().setText("my key", "my data");
pngReader.end();

Exception is thrown when setText() is called from getChunkListW() method in PngMetadata class by this cast:
return (ChunksListForWrite) chunkList;

Could you, please, fix it?

License

Let me apologise for stupid issue: I work for corporate and to satisfy their endless process, I need to know the license of this brick.

Something (and ideally) like "Apache 2"

Memory allocations in PngHelperInternal.skipBytes

From [email protected] on January 16, 2013 20:31:17

After running a test program in a memory profiler, I found that in the static PngHelperInternal.skipBytes method, a 32KB throwaway buffer is created in the first line -- each time the method is invoked. This is allocated each time skipBytes is used, which adds up to a fair amount of allocation over time.

To improve the memory behavior, the new byte[] allocation can be moved outside of the method, or better, perhaps the InputStream.skip(..) method could be used instead.

Original issue: http://code.google.com/p/pngj/issues/detail?id=22

Issue with ARGB generation on unix for UTF-8 images

From [email protected] on May 19, 2014 16:29:39

What steps will reproduce the problem? 1. Try to create a PNGJ png image with Japanese characters
2. The image has junk characters
3. It works in Windows but not on unix What is the expected output? What do you see instead? Should be Japanese What version of the product are you using? On what operating system? 2.0.0 (Linux) Please provide any additional information below.

Original issue: http://code.google.com/p/pngj/issues/detail?id=31

Slow write speeds

I am only getting around 3-5 MB/s writes on my SSD. Is there anyway to speed this up?

I am trying to go down the path of writing my own PNG stream writer, but cant seem to get the chunks to write correctly, I am only able to see the first chunk, i write.

However perhaps there is a method or way to speed up PNGJ that I am not aware of.
Any hints?

Mysterious PngReaderByte.readRow() issue

Does anyone know why the output printed each loop is true and true? What's even weirder is that the three lines read are the same object within each loop, but they will all be a different same object the next loop. I haven't been able to figure out what makes the difference between each loop as to whether or not a subsequent .readRow() will produce the same object as it did previously.

// Prepare the image reader
PngReader reader = new PngReaderByte(inputStream);
ImageInfo imageInfo = reader.imgInfo;

// Prepare the image writer
PngWriter writer = new PngWriter(outputImageFile, imageInfo);
for (int rowNum = 0; reader.hasMoreRows(); rowNum += 3)  // Input image's height is a multiple of 3
{
	// Read three horizontal stripes of the image
	ImageLineByte[] threeLines = new ImageLineByte[3];
	threeLines[0] = (ImageLineByte) reader.readRow();
	threeLines[1] = (ImageLineByte) reader.readRow();
	threeLines[2] = (ImageLineByte) reader.readRow();

	System.out.println(threeLines[0] == threeLines[1]); // Output: true
	System.out.println(threeLines[1] == threeLines[2]); // Output: true

	// Write the region to the image in the ImageWriter
	writer.writeRow(threeLines[0]);
	writer.writeRow(threeLines[1]);
	writer.writeRow(threeLines[2]);
}

The result is an image where each scanline is repeated 3 times. Example (you have to zoom way in):
image

Make method invalidateRaw() of class PngChunk public

From [email protected] on December 17, 2013 08:36:48

In order to edit, for instance, text chucks, the ChunkRaw attribute has to be cleared before writing a new png file. Otherwise, it still uses the old value instead. Therefore the invalidateRaw() method should be declared public, but is currently declared protected. What version of the product are you using? On what operating system? 2.0.0, Debian Wheezy

Original issue: http://code.google.com/p/pngj/issues/detail?id=27

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.