58FLOW

Android、行動経済学、ガジェットなどが好きです。日々感じたこと、ちょっとだけ役に立つかもしれないことなどいろいろ書きます。

コマンドラインでかんたんにGIFアニメーション作成

プロ生ちゃん Advent Calendar 2015 4日目に飛び入り参加しました。

www.adventar.org

はじめに

プロ生ちゃんのサイトでドット絵があったので使ってみたいと思います。ゲームなどに使う前に動いているところが見たかったのでGIFアニメーションを作ってみました。

いろいろGIFアニメーション制作ソフトはあると思いますが、今回はコマンドラインで作ります。ちょっと調べるimagemagickというのが使えそうでした。

環境

imagemagickのインストール

$ brew install imagemagick

ヘルプは

$ convert -help

いろいろオプションがありますね

素材画像

http://pronama.azurewebsites.net/pronama/download/

ここからドット絵をお借りしました。

f:id:flow58:20151203181443p:plainf:id:flow58:20151203181507p:plainf:id:flow58:20151203181516p:plainf:id:flow58:20151203181524p:plainf:id:flow58:20151203181531p:plainf:id:flow58:20151203181536p:plain

imagemagickを試す

$ convert /path.to/input/*.png /path.to/output/anime.gif

f:id:flow58:20151203181641g:plain

あれ?

透過画像を使っているので前の画像が消えずに何か表示がおかしくなっていますね。きっとオプションで回避可能なのでしょうが、うまくいかなかった

仕方ないのでPythonで背景を作る

それぞれの画像に背景をつけてからもう一回つくることにします。プログラマーっぽくPythonを使って背景色をつけることにしました。pipやPythonが環境に入っていなかったらPhotoshopとかでいいと思います。

PILインストール

PILというライブラリを使います。pip install PILでインストールできなかったので「pyenvでvirtualenvしててPILがインストール出来ない件」を参考にインストール

PILで透過画像に背景色を付ける方法

import Image

# 32 × 64の真っ白い画像(背景)を作る
bg = Image.new(mode='RGB', size=(32, 64) color=(255, 255, 255))

# 画像を取得
img = Image.open('/path.to/input_file.png')

# 背景に画像を合成
bg.paste(img, (0, 0), img)

# 保存
bg.save('/path.to/output_file.png')

実装例

上のコードをもとにディレクトリの中身全てに背景色をつけます。ディレクトリを作ったりいろいろごにょごにょしていますが重要なところは上のコードと変わりません。

import glob
import os
import Image


def get_output_path(input_path):
    tmp = input_path.split(os.sep)
    return os.sep.join([os.sep.join(tmp[0: -1]), 'result', tmp[-1]])


def set_background(img, rgb=(255, 255, 255)):
    bg = Image.new(mode='RGB', size=img.size, color=rgb)
    bg.paste(img, (0, 0), img)
    return bg


def make_dirs(path):
    try:
        os.makedirs(os.sep.join(path.split(os.sep)[0: -1]))
    except OSError:
        pass


def make(input_path, output_path=None):
    if output_path is None:
        output_path = get_output_path(input_path)
    make_dirs(output_path)
    img = Image.open(input_path)
    img = set_background(img)
    img.save(output_path)


def main():
    base_path = '/path.to/input/*.png'
    for file_name in glob.glob(base_path):
        make(file_name)


if __name__ == '__main__':
    main()

再びimagemagickを試す

$ convert /path.to/input/result/*.png /path.to/output/anime2.gif

f:id:flow58:20151203181656g:plain

できました!

アドベントカレンダー