🐥
[MetaPost] Animation GIF を作る
MetaPost で1コマずつ png を出力してまとめることにより Animation GIF を作る話.
以下で使用している MetaPost のインストールについてはこちら, julia のインストールについてはこちらを参照のこと.
0. 概要
- png 画像の作成(MetaPostで1コマずつ png を出力)
- GIF アニメーションの作成(julia を使用)
1. png 画像の作成
MetaPost を使って1コマずつ作成する.
1.1 作成のイメージ
MetaPost では1つのファイルで同時に多数の画像を作成することができる.
beginfig(1);
...
endfig;
beginfig(2);
...
endfig;
...
また通常のプログラミング言語のような制御構造もあるので, ループを使って自動的にたくさんの画像を同時に作成することができる. 特に, beginfig(i); ... endfig;
をループで回すことができる.
for i= 1 upto n:
beginfig(i);
... % i に依存した描画
endfig:
endfor
end
すなわち, i
番目の画像を第 i
コマ目と考えて画像を作成すれば, それらをまとめることによりパラパラ漫画の要領で GIF アニメーションを作成することができる.
1.2 プログラム
簡単なアニメーションの例として, 正方形が回転するだけのアニメーションを作成する.
各コマの png 画像を出力するプログラムは以下のとおり.
fig.mp
prologues := 3;
outputtemplate := "%j/%6c.png";
outputformat := "png";
u:=1in;
path bb,p;
bb = (-1.5u,-1.5u)--(1.5u,-1.5u)--(1.5u,1.5u)--(-1.5u,1.5u)--cycle;
p = (-u,-u)--(u,-u)--(u,u)--(-u,u)--cycle;
for i=0 upto 18:
beginfig(i);
draw p rotated 5i;
setbounds currentpicture to bb;
endfig;
endfor
end
プログラムのポイント:
- 出力ファイルのテンプレート
%j/%6c.png
-
%j
: プログラムファイルのベースネーム -
%6c
: 6桁で画像の連番を出力 -
fig/000001.png, fig/000002.png, ...
のような出力になる - これは後述する julia で GIF アニメーションを作るライブラリの仕様に準拠したもの
-
- 図形の回転
- 正方形を5度ずつ反時計周りに回転させる
- プログラムでいうと
draw p rotated 5i;
の部分 -
p
を5i
度回転させてdraw
する
- bounding box
- パス変数
bb
で bounding box を指定 - 原点を中心とした一辺
の正方形が回転するので, 最大2u の範囲まで描画される\pm\sqrt{2}u -
なので、原点を中心とした一辺\sqrt{2}<1.5 の正方形を bounding box とした3u - 具体的に bounding box をしていしているのは
setbounds currentpicture to bb;
の部分
- パス変数
- 対称性
- 正方形であるから,
i=0
とi=18
で図形は一致する -
i=18
はいらなかったかもしれない
- 正方形であるから,
2. Animation GIF の作成
Webサイトで作成できるサービスや個別のフリーソフトもいろいろあるが, 簡単にプログラミングできるので, julia で作成する.
プログラムは海外の julia の Q&A サイトにあったものを使用する. Plot
を使ってアニメーションを作成する記事はたくさん見つかるが, 既存の画像ファイルを使ってアニメーションを作成しているものはあまり見つからなかった.
前提:
- カレントフォルダのにある
fig
フォルダに png ファイルが格納されている - png ファイルは6桁の連番で名前がついている(これは
buildanimation
の制約なので変更できない) - フレームレートは 12fps (1秒間に12フレーム(コマ))
-
fig.gif
という名前の GIF ファイルをカレントフォルダに作成する
プログラム: (面倒なので REPL にコピペする前提で記載)
import Printf.@sprintf
import Plots:Animation, buildanimation
nframes =18
fnames = [@sprintf("%06d.png", k) for k in 0:nframes]
anim = Animation("fig", fnames); #fig is the folder name which contains the pngs
buildanimation(anim, "fig.gif", fps = 12, show_msg=false) #set a suitable fps
3. 結果
なんだか品質がいまいちな気がするけど, 今後の課題とします(笑).
Discussion