🐥

[MetaPost] Animation GIF を作る

2024/12/02に公開

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; の部分
    • p5i 度回転させて draw する
  • bounding box
    • パス変数 bb で bounding box を指定
    • 原点を中心とした一辺 2u の正方形が回転するので, 最大 \pm\sqrt{2}u の範囲まで描画される
    • \sqrt{2}<1.5 なので、原点を中心とした一辺 3u の正方形を bounding box とした
    • 具体的に bounding box をしていしているのは setbounds currentpicture to bb; の部分
  • 対称性
    • 正方形であるから, i=0i=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