WPF で APNG を表示する
.NET Framework WPF で APNG (Animated PNG) を表示しようとしたところ、ドンピシャなライブラリー等が見つからなかったので、C# 製 ライブラリーを fork して用意しました。
細かな仕様の部分で間違いやバグがあるかもしれませんが、自分用にはとりあえず使えるものができました。control ではないので Image control に表示するには、今のところコードビハインドでコード記述が必要です。
APNG の仕様について少し
APNG は、ファイル内に複数の PNG 画像があるようなフォーマットです。ただ、差分データによるアニメーションを実現できる仕様のため、単にファイル内の PNG 画像を取り出すだけはなく、画像の合成が必要です。デコードするだけでなく、この点も実装する上で手間ですね。

既存の APNG のライブラリー等について少し
C#, WPF で使えそうなライブラリーを検索すると次のようなものが見つかりました。
- GitHub - xupefei/XamlAnimatedPng: A simple library to display animated PNG (i.e., APNG) images in WPF and UWP
- Animated GIF を WPF 等でサポートするライブラリー作者による APNG 用ライブラリーのようですが、fork しただけで実装がないようです。
- ttp://apngwpf.codeplex.com/ ※ Google Chrome ではブロックされるため URL 表記のみ
- サービスが終了した CodePlex で公開されていた WPF 向けの APNG ライブラリー。C++/CLI 製で libpng を利用している模様。LGPL ライセンス。環境が古く、作者名等も不明なため使いませんでした。libpng を利用しているので、フレーム画像の合成などもきちんと動いているのかも。
- APNG Viewer - CodeProject
- C# 製。フレーム画像が差分データの場合が、考慮されていませんでした。
そして、上記ひとつ目の作者 xupefei 氏が、公開しているライブラリー APNG.NET。これを fork しました。
- GitHub - xupefei/APNG.NET: A fully-managed APNG parser, written in C#
- C# 製。XNA 向け。フレーム画像の合成は XNA 向けのコードで行っているので、合成部分を WPF 向けに用意しました。
APNG.NET for WPF
C# 製のライブラリー APNG.NET を使い、WPF 用の拡張メソッドを作っています。
APNG を BitmapSource に変換
合成済みのフレーム画像を BitmapSource オブジェクトとして取得します。
var apng = new APNG("a.png"); | |
var bitmaps = apng.ToBitmapSources(); | |
// Save to PNG files | |
foreach (var (bitmap, index) in bitmaps.Select((item, index) => (item, index))) | |
{ | |
using (var fileStream = new FileStream($"{index}.png", FileMode.Create)) | |
{ | |
var encoder = new PngBitmapEncoder(); | |
encoder.Frames.Add(BitmapFrame.Create(bitmap)); | |
encoder.Save(fileStream); | |
} | |
} |
APNG を Image control に表示
APNG からキーフレームアニメーションを生成し Storyboard を使ってアニメーションを表示します。
<Image Name="PngImage" /> |
var apng = new APNG("a.png"); | |
if (apng.IsSimplePNG) | |
PngImage.Source = BitmapFrame.Create( | |
apng.DefaultImage.GetStream(), BitmapCreateOptions.None, BitmapCacheOption.OnLoad); | |
else | |
apng.ToAnimation().CreateStoryboardFor(PngImage).Begin(PngImage); |