arsd.apng

Support for animated png files.

Please note this interface is not exactly stable and may break with minimum notice.

Members

Classes

ApngAnimation
class ApngAnimation

Class that represents an apng file.

ApngFrame
class ApngFrame

Represents a single frame from the file, directly corresponding to the fcTL and fdAT data from the file.

Enums

APNG_BLEND_OP
enum APNG_BLEND_OP
APNG_DISPOSE_OP
enum APNG_DISPOSE_OP

Functions

getApngBytes
ubyte[] getApngBytes(ApngAnimation apng)

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.

readApng
ApngAnimation readApng(ubyte[] data, bool strictApng, ApngAnimation delegate() factory)

Loads an apng file.

writeApngToData
void writeApngToData(ApngAnimation apng, void delegate(in ubyte[] data) sink)
writeApngToFile
void writeApngToFile(ApngAnimation apng, string filename)

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.

Structs

AnimationControlChunk
struct AnimationControlChunk

acTL chunk direct representation

ApngRenderBuffer
struct ApngRenderBuffer
FrameControlChunk
struct FrameControlChunk

fcTL chunk direct representation

Examples

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");
}

Meta

History

Originally written March 2019 with read support.

Render support added December 28, 2020.

Write support added February 27, 2021.

Suggestion Box / Bug Report