Introduction
APNG stands for animated PNG, which is similar to gif89, but gif89 only has 256 colors, so APNG might be a better choice in some scenarios. The APNG Viewer is based on the excellent .NET MNG Viewer written by SprinterDave, all credits go to him. It uses pure C#, without any third-party components, and with a very small footprint (only 30K).
Background
I've been searching for a native .NET APNG parser/viewer, but unfortunately, as what I have encountered before writing DBX Parser, I just could not find it (what the heck with Google, er?), so I had to do it by myself.
File Format
There are quite a few articles you might need to read in order to know what is APNG:
APNG is only a small extension to PNG, and it's compatible with PNG, so browsers like Internet Explorer and other viewers that do not support APNG will still display the first frame. Here we could see a diagram that could give us a brief idea of APNG file format:
Samples Files
Other Languages
Maybe you are looking for other languages. Here goes:
How It Works
It reads chunk by chunk as .NET MNG Viewer does, rebuilds each PNG frame according to the base header. If you look closer at the file format, you will find that the PNG specification is pretty simple.
Using the Code
First create a new instance of APNG
, then use the Load
function to read the file, then you can loop through NumEmbeddedPNG
, using the ToBitmap
function to save each frame to a PNG file.
Here goes a sample code:
APNG png = new APNG();
png.Load(@"animated.png");
for (int i = 0; i < png.NumEmbeddedPNG; i++)
{
Bitmap image = png.ToBitmap(i);
image.Save("frame" + i + ".png", ImageFormat.Png);
}
or with indexer:
APNG png = new APNG();
png.Load(@"animated.png");
for (int i = 0; i < png.NumEmbeddedPNG; i++)
{
png[i].Save("frame" + i + ".png", ImageFormat.Png);
}
Besides returning a new Bitmap
, the APNG
provides a SaveFile
that you could use to save the actual frame data (complete original PNG file data).
Points of Interest
Because I suffered a lot while finding such code, I contribute it here as others won't have to get crazy looking for it. If you have any comments or suggestions, please feel free to tell me, or just modify the code yourself.
History
- Version 1.0 - 2009-5-5 First release
- Version 1.1 - 2009-5-6 Added indexer, more detailed introduction