はじめに
今回は有名なGIF
サポートライブラリを比較してみたいと思います。
対象ライブラリは以下の3つ。
UniGif
mgGif
Unity-GifDecoder
GitHub - WestHillApps/UniGif: GIF image decoder for Unity.
GitHub - gwaredd/mgGif: A unity library to parse GIF files and extract the images as textures
GitHub - 3DI70R/Unity-GifDecoder: Gif decoding utility for Unity engine
評価
複数の観点から見た時評価は以下の通り。
ライブラリ名 | パフォーマンス | 利用しやすさ | コードの柔軟性 | オススメ度 |
---|---|---|---|---|
UniGif |
× | ◎ | △ | △ |
mgGif |
◎ | ○ | △ | ◎ |
Unity-GifDecoder |
○ | △ | ◎ | ◎ |
コードを利用せず出回っているサンプルコードを利用する場合はmgGif
,コードを書く場合はUnity-GifDecoder
がオススメかなと思います。
パフォーマンス
パフォーマンスに関してはmgGif > Unity-GifDecoder >>>>>> UniGif
のようなイメージになっています。
Library | Editor | Mono | IL2CPP |
---|---|---|---|
UniGif | 7321 ms | 3790 ms | 3178 ms |
Unity-GifDecoder | 365 ms | 123 ms | 88 ms |
mgGif | 247 ms | 112 ms | 80 ms |
mgGif (Unsafe Mode) | 280 ms | 106 ms | 70 ms |
GitHub - gwaredd/mgGif: A unity library to parse GIF files and extract the images as textures
こちらはmgGif
のGitHub
のReadme
に記載されているベンチマークです。
補足ではありますがmgGif
にはunsafe
を利用することでパフォーマンス向上できる機能が実装されています。
これをみるとUniGif
のパフォーマンスの悪さが顕著になっていますね。
またUnity-GifDecoder
のGC.Alloc
を含めた計測結果でも、Unity-GifDecoder >>>>>>> UniGif
となっています。
名前 | 処理時間 | GC.Alloc |
---|---|---|
Unity-GifDecoder | ~0.96ms | 385.1kb |
UniGif | ~19.27ms | 0.81gb |
GitHub - 3DI70R/Unity-GifDecoder: Gif decoding utility for Unity engine
またmgGif
とUnity-GifDecoder
のGC.Alloc
の比較もしてみたいということで自身でコードを書いて実験してみました。(Editor
上)
名前 | 処理速度 | GC.Alloc |
---|---|---|
mgGif(unsafe) | 11.63ms | 79.0kb |
mgGif | 6.53ms | 339.5kb |
Unity-GifDecoder(Memory) | 13.29ms | 111.0kb |
Unity-GifDecoder(File) | 14.60ms | 107.7kb |
処理速度ではmgGif > mgGif(unsafe) > Unity-GifDecoder(Memory) > Unity-GifDecoder(File)
、GC.Alloc
ではmgGif(unsafe) > Unity-GifDecoder(File) > Unity-GifDecoder(Memory) > mgGif
という結果になりました。
ただしこれはEditor
上で動作させており、メモリからGif
を読み取る場合はFile.ReadAllBytes
も含めた結果になっています。
思ったよりもUnity-GifDecoder
頑張っていますね。またEditor上だとmgGif > mgGif(unsafe)
になるのも公式ベンチマーク通りで少し関心しました。
利用しやすさ
利用しやすさというなんとも曖昧な評価基準ですが、あまり知識がなくても導入しやすいかどうかの指標として載せました。
UniGif
UniGif
は以下の点から評価できると考えています。
RawImage
に対してGif
適応するサンプルが同梱- コードが直感的に書ける
サンプルがあるので、自身でコードを書かなくて導入できることが魅力的ですね。
またコードもGif
のバイト列を渡せば、Texture2D
と画像の間隔(s)
が返ってくると直感的です。
yield return StartCoroutine(UniGif.GetTextureListCoroutine(www.bytes, (gifTexList, loopCount, width, height) => { /* Do something */ }));
mgGif
mgGif
に関しては以下の点を評価しました。
Renderer
に対してGif
適応するサンプルが同梱- コードがやや直感的
Renderer
に対してのサンプルがあるのは嬉しいですが、正直Image
のサンプルの方が嬉しいかなと思い少し減点しました。
またコードの書き方としては、直感的ではありますがUniGif
に比べるとC#
の知識が必要かなと言った感じがします。
byte[] data = File.ReadAllBytes( "some.gif" ); using( var decoder = new MG.GIF.Decoder( data ) ) { var img = decoder.NextImage(); while( img != null ) { Texture2D tex = img.CreateTexture(); int delay = img.Delay; img = decoder.NextImage(); } }
GitHub - gwaredd/mgGif: A unity library to parse GIF files and extract the images as textures
Unity-GifDecoder
最後にUnity-GifDecoder
に関してです。
- サンプルコードがない
- コードを書くには知識が必要
コードを書く場合はGif
の構造に関する知識が少し必要になってしまいます。
var frames = new List<Texture>(); var frameDelays = new List<float>(); using (var gifStream = new GifStream(yourFile)) { while (gifStream.HasMoreData) { switch (gifStream.CurrentToken) { case GifStream.Token.Image: var image = gifStream.ReadImage(); var frame = new Texture2D( gifStream.Header.width, gifStream.Header.height, TextureFormat.ARGB32, false); frame.SetPixels32(image.colors); frame.Apply(); frames.Add(frame); frameDelays.Add(image.SafeDelaySeconds); // More about SafeDelay below break; case GifStream.Token.Comment: var commentText = gifStream.ReadComment(); Debug.Log(commentText); break; default: gifStream.SkipToken(); // Other tokens break; } } }
GitHub - 3DI70R/Unity-GifDecoder: Gif decoding utility for Unity engine
Gif
の構造を知らない方はGifStream.Token.Image
ってなんやってなってしまいますよね。
GIFフォーマットの詳細 - とほほのWWW入門
利用するための障壁は少し高そうな印象です。
コードの柔軟性
コードの柔軟性についてですが、Unity-GifDecoder >>>>> UniGif = mgGif
といった感じでしょうか。
Unity-GifDecoder
がUniGif
・mgGif
に最も優っている点はStream
を扱えることです。
// Unity-GifDecoderではStreamを扱える var path = Path.Combine(Application.streamingAssetsPath, "sample.gif"); var file = File.ReadAllBytes(path); // ファイルから直接読み取り using var gifStream1 = new GifStream(path); // メモリから読み取り using var gifStream2 = new GifStream(file); using var gifStream3 = new GifStream(new MemoryStream(file));
UniGif
とmgGif
はバイト配列(メモリ上に確保されている)を受け取ってデコードを行うのですが、Unity-GifDecoder
ならメモリだけでなくファイルやネットワークなどから読み取りデコードをすることができます。
またUnity-GifDecoder
はメインスレッド以外でも動作することがReadme
に記載されている点もありがたいですね。
結論
UniGif
があまりにパフォーマンスが悪いので私的には除外ですかね。
mgGif
とUnity-GifDecoder
ではそこまでのパフォーマンス差がありませんし、コードがある程度描ける人ならUnity-GifDecoder
が良いのではないのかなと個人的には思います。
ただ誤解してほしくないのはUniGif
を利用するなといった訳ではないことに注意してください。
サンプルコードもしっかりと書かれていますし、それぞれの環境・状況に応じて適切に選択してもらえれば幸いです。
それぞれのライブラリの使い方
www.hanachiru-blog.com
www.hanachiru-blog.com
www.hanachiru-blog.com