Λάδι Βιώσας

http://profile.hatena.ne.jp/kenkitii/

はてなハイクの人力シムシティをフラッシュアニメにするスクリプト

jkondoさんの今日の日記を読んでいたら、人力シムシティなるものが紹介されてました。これはおもろい!けど、一枚一枚を画像でみるんじゃなくて、パラパラ漫画みたいにしてみたいなあ、、、と思ったので、pythonでflashアニメを作るスクリプトを書いてみました。

  • haiku-anime.py
import os
import re
import urllib2
from subprocess import *
from optparse import OptionParser

from ming import *

PATH_TO_FOTO = 'fotos'

def extract_fotos(url):
    links, pages_links = [], []
    query, page = url, 1
    foto = re.compile('img src="(http://f.+?)"')

    while True:
        links = []
        for line in urllib2.urlopen(query):
            r = foto.search(line)
            if r:
                links.append(r.group(1))

        if links == []: break
        pages_links += links
        page += 1
        query = url + "?page=%i" % page

    return pages_links[::-1]

def download_foto(url):
    if not os.access(PATH_TO_FOTO, os.F_OK):
        os.mkdir(PATH_TO_FOTO)

    dat = urllib2.urlopen(url).read()
    filename = os.path.basename(url)
    open(os.path.join(PATH_TO_FOTO, filename), "wb").write(dat)
    return filename

def png2dbl(filename):
    path_to_file = os.path.join(PATH_TO_FOTO, filename)
    call(["png2dbl", path_to_file])
    return filename[:-3] + 'dbl'
    
def create_movie(dbls, swf_name):
    X_MARGIN, Y_MARGIN = 20, 20

    m = SWFMovie()
    m.setRate(1.0)
    image = SWFBitmap(os.path.join(PATH_TO_FOTO, dbls[0]))
    swf_size_x = image.getWidth() + X_MARGIN * 2 
    swf_size_y = image.getHeight() + Y_MARGIN * 2
    m.setDimension(swf_size_x, swf_size_y)

    for dbl in dbls:
        item = m.add(SWFBitmap(os.path.join(PATH_TO_FOTO, dbl)))
        item.moveTo(X_MARGIN, Y_MARGIN)
        m.nextFrame()
        m.remove(item)

    m.save(swf_name)

def main():
    usage = "usage: %prog url [options]"
    parser = OptionParser(usage)
    parser.add_option("-o", "--output", dest="output", help='output filename.')
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("invalid arguments")

    output = "test.swf"
    if options.output: output = options.output
    images = extract_fotos(args[0])
    pngs = map(download_foto, images)
    dbls = map(png2dbl, pngs)
    create_movie(dbls, output)
    print "done."

if __name__ == "__main__":
    main()

上記のスクリプトでは、mingというflashコンテンツを生成するライブラリを使っているので、動作にはmingが必要です。http://sourceforge.net/projects/ming から、ming-0.3.0.tar.gz, ming-py-0.3.0.tar.gz を取ってきましょう。ちなみに、macosxの場合、以下のような手順でpythonからmingを使えるようになります。

sudo port install jpeg libpng libungif zlib 
tar zxvf ming-0.3.0.tar.gz
tar zxvf ming-py-0.3.0.tar.gz
cd ming-0.3.0 
./configure "LDFLAGS=-L/opt/local/include -L/opt/local/lib" "CPPFLAGS=-I/opt/local/include -I/opt/local/lib" "CFLAGS=-I/opt/local/include -I/opt/local/lib" 
make 
sudo make install 
cd py_ext
python setup.py build
sudo python setup.py install

使ってみる

こんな感じ↓で使うと、

python haiku-anime.py http://h.hatena.ne.jp/keyword/%e4%ba%ba%e5%8a%9b%e3%82%b7%e3%83%a0%e3%82%b7%e3%83%86%e3%82%a3 -o simcity.swf

こんな感じのswfファイルが生成されます。ちなみに生成元にした、はてなハイクはコレです。てか、同じ画像サイズのものでないと、うまくアニメになりませんね、、、