はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】有名なGIFサポートライブラリについて比較してみる(UniGif, mgGif, Unity-GifDecoder)

評価

複数の観点から見た時評価は以下の通り。

ライブラリ名 パフォーマンス 利用しやすさ コードの柔軟性 オススメ度
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

こちらはmgGifGitHubReadmeに記載されているベンチマークです。

補足ではありますがmgGifにはunsafeを利用することでパフォーマンス向上できる機能が実装されています。

これをみるとUniGifのパフォーマンスの悪さが顕著になっていますね。

またUniGifとUnity-GifDecoderGC.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

またmgGifUnity-GifDecoderGC.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 */ }));

GitHub - WestHillApps/UniGif: GIF image decoder for Unity.

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-GifDecoderUniGifmgGifに最も優っている点は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));

UniGifmgGifはバイト配列(メモリ上に確保されている)を受け取ってデコードを行うのですが、Unity-GifDecoderならメモリだけでなくファイルやネットワークなどから読み取りデコードをすることができます。

またUnity-GifDecoderはメインスレッド以外でも動作することがReadmeに記載されている点もありがたいですね。

結論

UniGifがあまりにパフォーマンスが悪いので私的には除外ですかね。

mgGifUnity-GifDecoderではそこまでのパフォーマンス差がありませんし、コードがある程度描ける人ならUnity-GifDecoderが良いのではないのかなと個人的には思います。

ただ誤解してほしくないのはUniGifを利用するなといった訳ではないことに注意してください。
サンプルコードもしっかりと書かれていますし、それぞれの環境・状況に応じて適切に選択してもらえれば幸いです。

それぞれのライブラリの使い方

www.hanachiru-blog.com
www.hanachiru-blog.com
www.hanachiru-blog.com