Python, PillowでアニメーションGIFを作成、保存
Pythonの画像処理ライブラリPillowを使うと、アニメーションGIF(GIFアニメ)を作成・保存できる。
ここでは以下の内容について説明する。
Image.save()
でGIFとして保存- アニメーションGIFを生成するサンプルコード
Image.save()
の引数- 引数
append_images
- 引数
optimize
- 引数
loop
- 引数
duration
- 引数
Image.save()でGIFとして保存
Image.save()
を使うと、複数の画像からアニメーションGIFを生成して保存できる。
im.save('out.gif', save_all=True, append_images=[im1, im2, ...])
最初のフレームの画像im
に、画像のリスト[im1, im2, ...]
が追加されアニメーションGIFのファイルout.gif
が生成される。
詳細は以下の公式ドキュメント参照。
具体的なサンプルコードおよび引数については後述。
アニメーションGIFを生成するサンプルコード
PillowのImageDraw
で徐々に大きくなる円を描画しGIFファイルとして保存するサンプルコードを示す。
from PIL import Image, ImageDraw
images = []
width = 200
center = width // 2
color_1 = (0, 0, 0)
color_2 = (255, 255, 255)
max_radius = int(center * 1.5)
step = 8
for i in range(0, max_radius, step):
im = Image.new('RGB', (width, width), color_1)
draw = ImageDraw.Draw(im)
draw.ellipse((center - i, center - i, center + i, center + i), fill=color_2)
images.append(im)
for i in range(0, max_radius, step):
im = Image.new('RGB', (width, width), color_2)
draw = ImageDraw.Draw(im)
draw.ellipse((center - i, center - i, center + i, center + i), fill=color_1)
images.append(im)
images[0].save('data/dst/pillow_imagedraw.gif',
save_all=True, append_images=images[1:], optimize=False, duration=40, loop=0)
はじめに空のリストimages
を作成。2つのfor文で徐々に大きくなる円の画像を作成しimages
に追加、最後にsave()
でGIFを生成している。
以下のようなアニメーションGIFファイルが生成される。
Pillowで円などの図形を描画する方法については以下の記事参照。
そのほか、モザイクを徐々にかけるアニメーションGIFの例は以下の記事を参照。
Image.save()の引数
基本的には、画像(Image
オブジェクト)のリストを用意すれば以下のコードでアニメーションGIFを作成できる。
images[0].save('data/dst/pillow_imagedraw.gif',
save_all=True, append_images=images[1:], optimize=False, duration=40, loop=0)
上の例のように図形を描画して画像を生成するのではなく、複数の既存画像からGIFアニメを作成したい場合も、画像を読み込んでリストに格納すれば同様に処理できる。
引数append_images
最初のフレームの画像に対してsave()
メソッドを使い、残りの画像をリストを引数append_images
に渡す。
上の例ではスライスで2枚目以降の画像を指定している。append_images=images
としてしまうと、最初のフレームが2回繰り返されてしまうので注意。
引数optimize
ソースコードを追っていないのでどういう処理がされているのか分からないが、デフォルト(optimize=True
)だと近似した画像が続くと省略されたり、意図しない結果になる場合がある。
出力ファイルがおかしかったらoptimize=False
にしてみると解決するかもしれない。
引数loop
引数loop
はループの回数。loop=0
とすると無限ループになる。
デフォルトだと1回アニメーションして終了なので注意。
引数duration
引数duration
は各フレームの表示時間で、単位はミリ秒。あまりにも小さい値だと反映されない。