MATLABでGIFアニメーションを作成するベストプラクティス

この記事では，MATLABでGIFアニメーションを作成するベストプラクティスを紹介します．
[MATLAB Flipbook Mini Hack](https://jp.mathworks.com/matlabcentral/contests/2023-matlab-mini-hack.html)の情報を参考に，記事を執筆しています．

# はじめに
[MATLABコミュニティ](https://jp.mathworks.com/matlabcentral)では，定期的に[コンテスト](https://jp.mathworks.com/matlabcentral/contests.html)を開催しています．
2023年11月6日～12月3日の期間，[MATLAB Flipbook Mini Hack](https://jp.mathworks.com/matlabcentral/contests/2023-matlab-mini-hack.html)が開催されました．
これは，2000文字以内のMATLABコードで，どのような素晴らしいアニメーションを作成できるか競うコンテストです．
GIFアニメーションを作成するMATLABコードを投稿し，生成されたGIFを人気投票します．

去年と一昨年に開催された画像コンテスト[(1)](https://jp.mathworks.com/matlabcentral/contests/2022-matlab-mini-hack.html)[(2)](https://jp.mathworks.com/matlabcentral/contests/20th-anniversary-matlab-minihack.html)は，コンテスト終了後もコードと画像が公開されているので，今回のコンテスト参加者のデータも公開状態のままだと思います．

コンテスト主催者が用意した素晴らしいコードを
**MATLABでGIFアニメーションを作成するベストプラクティス**として紹介します．

# アニメーション生成関数
MATLABコードは，コンテスト参加者が共通して利用する`contestAnimator`関数と各自で記述する`drawframe`関数に分かれます．
`contestAnimator`関数は，以下の通りです．
```MATLAB:contestAnimator.m
function contestAnimator()
    animFilename = 'animation.gif'; % Output file name
    firstFrame = true;
    framesPerSecond = 24;
    delayTime = 1/framesPerSecond;
    % Create the gif
    for frame = 1:48
        drawframe(frame)
        fig = gcf(); 
        fig.Units = 'pixels';
        fig.Position(3:4) = [300,300];
        im = getframe(fig);
        [A,map] = rgb2ind(im.cdata,256);
        if firstFrame
            firstFrame = false;
            imwrite(A,map,animFilename, LoopCount=Inf, DelayTime=delayTime);
        else
            imwrite(A,map,animFilename, WriteMode="append", DelayTime=delayTime);
        end
    end
end
```
最初の4行には，設定が書かれています．
まず，出力するファイル名を指定します．
次に，`firstFrame`変数を`true`で宣言します．GIFアニメーション作成の1フレーム目とそれ以降のフレームでは処理が違うため，その分岐に使用します．
そして，1秒間の動画を何枚の画像で構成するか，1枚の画像を何秒表示するか指定します．

`for`文で画像を1枚づつファイルに追加することで，GIFアニメーションを作成します．
今回は，48枚の画像を用いて2秒のGIFアニメーションを作成します．
`drawframe(frame)`は，各自で記述する画像作成関数です．
作成した画像について，幾つかの整形をした後，`imwrite`関数でGIFアニメーションを作成，更新します．

`im.cdata`は，`300x300x3 uint8`型のデータです．ピクセル毎のRGB値が格納されています．
`map`は，`Nx3 double`の`N`色カラーマップです．画像に使われている色が格納されています．
`A`は，`300x300 uint8`型のデータです．ピクセル毎に対応する`map`のインデックスが格納されています．

# アニメーション作成例
どのようなGIFアニメーションが作成できるのか，試してみます．
[こちら](https://jp.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13302)のコードを参考に，以下のコードでGIFアニメーションを作成します．
```MATLAB:drawframe.m
function drawframe(f)
    cla
    text(0.2,0.5,sprintf('%2d',f),fontsize=100);
end
```
![animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/e2a7baad-6371-114a-d679-32d2e06738c9.gif)

`contestAnimator.m`を実行するだけで．GIFアニメーションを簡単に作成できました．
~~1秒間に24秒の画像が表示されると，目に優しくなさそうです．~~
[ギャラリー](https://jp.mathworks.com/matlabcentral/communitycontests/contests/6/entries)からお気に入りのGIFを見つけて，皆さんも遊んでみてはいかがでしょうか？

自分も3つほどコードを投稿してみました．
frame数やdelayTimeの変更で，緩やかに変化する長いGIFアニメーションを作成できます．
|![](https://jp.mathworks.com/responsive_image/300/300/0/0/0/cache/matlabcentral/communitycontests/uploaded_files/14797/animation.gif?a=true)|![](https://jp.mathworks.com/responsive_image/300/300/0/0/0/cache/matlabcentral/communitycontests/uploaded_files/14777/animation.gif?a=true)|![](https://jp.mathworks.com/responsive_image/300/300/0/0/0/cache/matlabcentral/communitycontests/uploaded_files/14767/animation.gif?a=true)|
|:---:|:---:|:---:|
|[Simplex-lattice design](https://jp.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13367)|[Incremental Lattice Design](https://jp.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13357)|[Bayesian optimization](https://jp.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13352)|

# 終わりに
GIFアニメーションは，QiitaやGitHubを含む色々なサイトで利用できます．
GIFアニメーションを積極的に活用していきましょう．