PythonのプログラムでGIFアニメーションを作ろう

SNSで見かけるパラパラ漫画を作りたいなー。なになに、えーっと調べてみると「GIFアニメーション」というみたいだ!

博士蛙

ほほう。GIFアニメーションを作るのですね。GIFアニメーションを作るには、色々と方法がありますが、Pythonでのプログラミングで簡単につくれますよ。

えっ、専用のソフトやアプリは必要ではないのですか??

博士蛙

はい。Pythonから利用可能ないくつかの「ライブラリ」を使用することで、かんたんなプログラミングでGIFアニメーションが作成可能です。さっそく、GIFアニメーションをつくるプログラミングについて紹介します。

今回の記事では,Pythonのプログラムで簡単なアニメーションを作る方法について書きます.

といっても,動画ファイルを作成するのではなく,複数の画像ファイルを合体させて,下記のようなGIFアニメーションを作成します.


プログラムは,2種類紹介します.

1つ目は,グラフの作成などに用いる「matplotlib」というライブラリを使う方法です.

2つ目は,Pythonで動画編集を行える「MoviePy」というライブラリを使う方法です.

この2つの方法を比較すると,1つ目の「matplotlib」を使った場合の方が,短い時間でアニメーションを作成できます.
一方,「MoviePy」を使った場合の方が,簡単にプログラムを書くことができます.

では,早速中身に入りましょう

1. matplotlibを使ってGIFアニメを作成

まず,アニメーションの元になる画像を数枚用意します.

紙にペンで簡単なイラストを数枚描いても良いですし,iPadを使ってイラストを作っても良いです.

今回は,鳥??が羽ばたいている様子を数枚のイラストで用意しました.


Pythonのプログラムとアニメーションの元になる画像ファイルのディレクトリ構成は,下記のようになります.


./

├── main.py

└── img

    ├── 1.png

    ├── 2.png

    ├── 3.png

    ├── 4.png

    ├── 5.png

    ├── 6.png

    ├── 7.png

    ├── 8.png

    └── 9.png


アニメーションの元になる画像は,「img」というフォルダに保存します.

作成したPythonのプログラムは,下記のようになります.(動作確認をした環境は,macOS 10.15.7とWindow 10です.)


from PIL import Image
import glob
from natsort import natsorted
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import datetime

# name of image file folder
folderName = "./img"
# create list of image files name
picList_0 = glob.glob(folderName + "/*.png")

picList = natsorted(picList_0)
#create of fig object
fig = plt.figure()

# delete axis
plt.axis("off")
# create empty list
ims = []
# create list of graph data
for i in range(len(picList)):
tmp = Image.open(picList[i])
ims.append([plt.imshow(tmp)])

# create animation data
ani = animation.ArtistAnimation(fig, ims, interval=100)
# save
now = datetime.datetime.now()
save_filename = "./img/" + now.strftime('%Y%m%d_%H%M%S') + ".gif"
ani.save(save_filename)


まず,画像ファイルが保存されているフォルダ名をfolderNameに格納します.

次に,folderNameに保存している画像ファイルのファイル名の一覧をpicList_0に格納します.
ここでは,「glob」というライブラリを使用して,ファイル名の一覧を取得します.
「glob」は,標準ライブラリなので,pipコマンドでインストールしなくても使用できます.

さらに,取得したファイル名の一覧を自然順に並べ直します.
自然順に並べ直したリストは,picListに格納します.
ここでは,「natsort」というライブラリを使用します.
「natsort」を使うには,ターミナルで下記のコマンドを実行して,ライブラリをインストールします.

「pip3 install natsort」

PNG画像を読み込んでアニメーションを作っているのは,「ani = animation.ArtistAnimation(fig, ims, interval=100)」の部分です.
引数は,figオブジェクトと,imsというリストです.

imsの中には,picListに格納したファイル名のPNG画像を全て保存したものです.
forループで,ファイル数分の処理を繰り返します.
Image.open()で,引数に与えたファイル名の画像を読み込みます.
plt.imshow()で,引数に与えた画像データをmatplotlibで扱えるよになります.

animation.ArtistAnimation()」の一番最後の引数の「interval」では,アニメーションにおいて画像と次の画像の切り替えの時間(ミリ秒)を指定します.

作成したアニメーションのデータを保存するには,「ani.save()」で行います.
引数にはファイル名を与えます.
ここでは,プログラムを実行した時刻を「now.strftime('%Y%m%d_%H%M%S')」によって付けます.

作成したアニメーションは「.gif」という拡張子で保存します.
この形式のファイルのことをGIFファイルと呼びます.

実際に作成したアニメーションを,下記に示します.



2. MoviePyを使ってGIFアニメを作成

次に,「MoviePy」というライブラリを使ってアニメーションを作成します.

「glob」を使って画像のファイル名の一覧を取得して,「natsort」によって自然順に一覧を並び替えるまでは全く同じです.

「MoviePy」を使うには,ターミナルで下記のコマンドを実行します.

「pip3 install moviepy」

作成したプログラムは,下記の通りです.


from moviepy.editor import ImageSequenceClip
import glob
from natsort import natsorted
import datetime

# name of image file folder
folderName = "./img"
# create list of image files name
picList_0 = glob.glob(folderName + "/*.png")
picList = natsorted(picList_0)

# create animation data
clip = ImageSequenceClip(picList,fps=100)

# save
now = datetime.datetime.now()
save_filename = "./img/" + now.strftime('%Y%m%d_%H%M%S') + ".gif"
clip.write_gif(save_filename)
clip.close()


アニメーションのデータを作成している部分は,「clip = ImageSequenceClip(pickList,fps=100)」です.
引数として,画像ファイル名のリストである「pickList」と画像の切り替え時間を指定する「fps」です.

「ims」は,先程の「matplotlib」を使った場合と異なり,ここでは,ファイル名のリストさえ用意すれば良いです.

また,ファイルの保存には,「clip.write_gif(save_filename)」と記述します.

「matplotlib」を使ってプログラムを書いた場合と比べて,とても簡単に書けました.


3. 実行時間の比較

「matplotlib」と「MoviePy」を使って記述した2つのプログラムを実行して,実行時間を比較してみます.

実行時間の比較には,「time」というライブラリを使います.
ここでは,プログラム実行直後と終了直前の時間を記録して,これらの差分を「実行時間」とします.


import time
s_time = time.time()

# 実行時間を計測したい処理

e_time = time.time() - s_time
print(f'実行時間は,{e_time}秒')


それぞれのプログラムに対して,2回計測しました.

「matplotlib」を使ったプログラムの実行時間

  • 1回目:3.018721103668213 秒
  • 2回目:3.0852649211883545 秒

「MoviePy」を使ったプログラムの実行時間

  • 1回目:5.767834901809692 秒
  • 2回目:5.362166166305542 秒

 2秒から2.5秒程度の差があることが確認できました.

今回の記事の内容は,以上となります.
ご不明な点や質問などありましたら,コメント欄やお問い合わせフォームからよろしくお願いします.
最後まで読んでいただき,ありがとうございました.

コメント

このブログの人気の投稿

Macのクリーンインストール失敗!【1008F】に遭遇したときの記録

Python Tips 複数のファイルのパス名を読み込んで自然順に並べる方法