Click here to Skip to main content
Click here to Skip to main content

APNG Viewer

By , , 6 May 2009
 

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Authors

SprinterDave
Software Developer (Senior) Bally Technologies
United States United States
Member
I've been software developer since early 1991. My focuses have ranged from deeply embedded (Intel and ARM architectures,) to firmware (C and C++), to application level software under Linux and Windows (C, C++ and C#.) Applications developed with .NET under Windows have been primarily test and support applications for other development activities.

Huisheng Chen
Architect www.xnlab.com
Australia Australia
Member
I was born in the south of China, started to write GWBASIC code since 1993 when I was 13 years old, with professional .net(c#) and vb, founder of www.xnlab.com
 
Now I am living in Sydney, Australia.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionAn updated code for this articlememberamemiyasss23 Jul '12 - 20:18 
I have written an apng parser using C#, with the help of this article. The project is hosted at https://github.com/xupefei/APNG.NET[^] . Thanks Dave and Chen for the great work!
AnswerRe: An updated code for this articlememberHuisheng Chen24 Jul '12 - 19:16 
nicely done! Shucks | :->
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

QuestionExtend Bitmap to display one frame at a time?memberdivStar26 Nov '10 - 8:14 
Hi there,
 
I want to use an APNG file instead of a GIF, because I want per-pixel-alpha. How would I go about displaying it? I am guessing the best idea is to inherit the Image-class and add some sort of timer within that to take care of the frame to display. Do you know if something like that has already been written?
 
The library is super-small and powerful! I will also try to hook it up to a resource file. It seems that I'll have to save the APNG file as a file inside the resource file - not as an image (at least that's what it seems). I'll be experimenting and if I code something useful, I'll let you know. Definitely a nice project. Thank you very much for sharing.
 
Igor.
AnswerRe: Extend Bitmap to display one frame at a time?memberUnruled Boy28 Jan '11 - 19:55 
sorry to answer you late, I think a quick and dirty solution is to use timer with interval retriving from apng file.
 
for a better solution, you can convert it to gif at runtime
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

Generalblend_op are not supported :(membereviral16 Oct '10 - 11:00 
Hello...
 
Nice ! but i think you don't deal with blend_op as specified into APNG specifications Frown | :(
 
When i use APNG anime maker to buid APNG files with optimisations enable (only image diff is stored) my anim is 600ko instead of 5mo !!!
 
http://sites.google.com/site/cphktool/apng-anime-maker[^]
 
But it doesn't display correctly with your APNG csharp implementation Frown | :(
 
Do you think you can update your code to be able to deal with that ???
 
Thanks
 
Eviral
 
PS:I'm using your nide code to implement a Custom Content Importer for XNA 3.1
GeneralMy vote of 1memberabcd1234f10 Aug '09 - 8:38 
-
GeneralRe: My vote of 1memberSmart K84 Dec '09 - 10:17 
You should at least wrote why you're giving such a low rating. But in the case, you didn't know it, 5 is the best out here, ya know.
 
The wisdom is to see things truthfully.

GeneralJust.... awesome!!memberAPBilbo30 Jun '09 - 11:44 
This look really impressing. I've succesfully runned it under NET.CF with some of the sample apng's (though Bitmap.FromStream is not available and had to change it for the Bitmap(Stream) constructor). I've found a problem with some of the sample images here:
http://www.spreadfirefox.com/node/1872
 
Oh, and +1 for the delay reading Smile | :) .
 
Keep it up!
GeneralRe: Just.... awesome!!memberUnruled Boy30 Jun '09 - 17:35 
yes, you are right about the not properly handling your samples, I encountered such problem before but I fixed(I assumed), I will look into again.
 
thanks a lot.
 
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

GeneralGreat Job~~~memberpen_lake10 May '09 - 5:16 
5 分!! 寫的很好...繼續加油啊.
GeneralRe: Great Job~~~memberUnruled Boy10 May '09 - 19:03 
谢谢 Big Grin | :-D
 
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

GeneralSuggestionmemberharold aptroot5 May '09 - 7:40 
Nice (5!), but, I would have made an indexer on the APNG, to get the X-th bitmap;
 

GeneralRe: SuggestionmemberUnruled Boy5 May '09 - 15:42 
yes, good point, I will add it in next update
 
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

Generalplease commentmemberUnruled Boy4 May '09 - 20:09 
thanks a lot
 
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

GeneralRe: please commentmembernicholas_pei6 May '09 - 2:46 
U know ,As a Chinese, his native tongue is Chinese, not english.That's why there is little comment.
顶你,大哥。
GeneralRe: please commentmemberUnruled Boy6 May '09 - 3:58 
我顶。。。好歹投个票啊 Big Grin | :-D
 
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

Generalrecompile images?memberagent_zer024 Oct '09 - 15:33 
Your program saved me a ton time, thanks! Is there anyway to have it recompile all of the images back into an apng? (yes, I know there is that lame firefox plugin) but when you have 60 images to compile, it takes way too long! Keep up the good work!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 6 May 2009
Article Copyright 2009 by SprinterDave, Huisheng Chen
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid