Class that represents an apng file.
Represents a single frame from the file, directly corresponding to the fcTL and fdAT data from the file.
It takes the apng file and feeds the file data to your sink delegate, the given file, or simply returns it as an in-memory array.
Loads an apng file.
It takes the apng file and feeds the file data to your sink delegate, the given file, or simply returns it as an in-memory array.
acTL chunk direct representation
fcTL chunk direct representation
Demo creating one from scratch
import arsd.apng; void main() { auto apng = new ApngAnimation(50, 50); auto frame = apng.addFrame(25, 25); frame.data[] = 255; frame = apng.addFrame(25, 25); frame.data[] = 255; frame.frameControlChunk.delay_num = 10; frame = apng.addFrame(25, 25); frame.data[] = 255; frame.frameControlChunk.x_offset = 25; frame.frameControlChunk.delay_num = 10; frame = apng.addFrame(25, 25); frame.data[] = 255; frame.frameControlChunk.y_offset = 25; frame.frameControlChunk.delay_num = 10; frame = apng.addFrame(25, 25); frame.data[] = 255; frame.frameControlChunk.x_offset = 25; frame.frameControlChunk.y_offset = 25; frame.frameControlChunk.delay_num = 10; writeApngToFile(apng, "/home/me/test.apng"); }
Demo reading and rendering
import arsd.simpledisplay; import arsd.game; import arsd.apng; void main(string[] args) { import std.file; auto a = readApng(cast(ubyte[]) std.file.read(args[1])); auto window = create2dWindow("Animated PNG viewer", a.header.width, a.header.height); auto render = a.renderer(); OpenGlTexture[] frames; int[] waits; foreach(frame; a.frames) { waits ~= render.nextFrame(); // this would be the raw data for the frame //frames ~= new OpenGlTexture(frame.frameData.getAsTrueColorImage); // or the current rendered ersion frames ~= new OpenGlTexture(render.buffer); } int pos; int currentWait; void update() { currentWait += waits[pos]; pos++; if(pos == frames.length) pos = 0; } window.redrawOpenGlScene = () { glClear(GL_COLOR_BUFFER_BIT); frames[pos].draw(0, 0); }; auto tick = 50; window.eventLoop(tick, delegate() { currentWait -= tick; auto updateNeeded = currentWait <= 0; while(currentWait <= 0) update(); if(updateNeeded) window.redrawOpenGlSceneNow(); //}, //(KeyEvent ev) { //if(ev.pressed) }); // writeApngToFile(a, "/home/me/test.apng"); }
Originally written March 2019 with read support.
Render support added December 28, 2020.
Write support added February 27, 2021.
Support for animated png files.