Try creating APNG from JavaFX

Create Animation PNG (APNG)

This is a continuation of Last time.

Chunks required for APNG

In addition to the required chunks (IHDR / IDAT / IEND)

Chunk Contents
acTL Inform that it is APNG
fcTL Inform the frame
fdAT Image data of frame

The above three. See Animated PNG graphics for more information.

Difference between IDAT and fdAT

Unlike IDAT, fdAT has a sequence number in the first 4 bytes. Please note that this is different from the frame number.

It looks like the one below.

chunk Frame number Sequence number
acTL(none) (none)
fcTL 0 0
IDAT 0 (none)
IDAT 0 (none)
IDAT 0 (none)
fcTL 1 1
fdAT 1 2
fdAT 1 3
fdAT 1 4
fcTL 2 5
fdAT 2 6
fdAT 2 7
fdAT 2 8

Excluding the actual PNG file, IDAT and fdAT are split into multiple parts, but this is just one file split into chunks. It will be to reduce memory consumption by outputting to the buffer size when handling Defrator.

Bring animation data quickly

Pick it up from Pixiv using Ank-Pixiv-Tool. If you take the metadata together, you will get two .zip and .json. Actually, the frame data is contained in the .json file. Without this data, the timeline will be unknown.

Contents of json file

{
 "info": {
  "illust": {

//abridgement

  "path": [
   {
    "src": "https://i.pximg.net/img-zip-ugoira/img/xx ....  xx.zip",
    "frames": [
     {
      "f": "000000.jpg ",
      "d": 50


//abridgement

    "referrer": "https://www.pixiv.net/member_illust.php?xxxxx"
   }
  ]
 }
}

All you have to do is earn f and d under info-> path [0]-> frames []. f is the file name and d is the delay (in 1ms increments).

However, Java does not have a standard JSON library, so I will bring it from the outside.

Save

The difference from the last time is that it supports alpha channel and separates APNG output and IDAT chunk. (I tried to divide the size into 64KB-12byte.)

This is a difference in how to use Deflater. Last time, if the compressed data could not be larger than the original, the buffer size was decided to be the same as the input size, but it is switched to the fixed buffer.

		Deflater encoder = new Deflater();
		encoder.setInput(buffer);
		encoder.finish();

		int compresslength;
		do {
			byte[] outbuffer = new byte[buffersize];
			PNGChunk data = new PNGChunk(ChunkTYPE.IDAT);
			compresslength = encoder.deflate(outbuffer);
			data.setBuffer(outbuffer);
			data.setLength(compresslength);

			if (compresslength != 0) {
				list.add(data);
			}
		} while (compresslength != 0);

The finished product

This time, I have decided on a file to move it for the time being.

https://github.com/tsudon/Ugoira2GIF

Recommended Posts

Try creating APNG from JavaFX
Try Spring Boot from 0 to 100.
Try using Cocoa from Ruby
Creating ElasticSearch index from Java