Python, PillowでアニメーションGIFを作成、保存

Posted: | Tags: Python, Pillow, 画像処理

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

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は各フレームの表示時間で、単位はミリ秒。あまりにも小さい値だと反映されない。

関連カテゴリー

関連記事