GML(Graffiti Markup Language)を画像化するレシピ

用意するもの

  • Python と PIL(Python Imaging Library) と lxml
  • GMLデータ

PythonとPIL、lxmlモジュールはシステムパッケージでもソースからの コンパイルでもどちらでもよいです。 以下はUbuntuでインストールする手順です。

$ sudo apt-get python python-imaging python-lxml

GMLデータは #000000book.com から取得したものを使います。

http://000000book.com/data/ から適当なものを取得します。 今回は Tag #148 を使ってみます。

作り方

#000000book.comからデータを取得してPNG形式データを出力するスクリプトは 以下になります。 GmlObject にファイルパスまたはURLを渡してインスタンスを生成し、 それを GmlDrawer にぶっこんで set_canvas_size してから、 draw します。 (日本語じゃなくなってるな。。)

import urllib2
from lxml import etree
import Image
import ImageDraw
import ImageOps


class GmlObject(object):

    def __init__(self, gmlfilename):
        gml = etree.parse(gmlfilename)
        self.xs = [float(i.text) for i in gml.xpath("//pt/x")]
        self.ys = [float(i.text) for i in gml.xpath("//pt/y")]
        self.zs = [float(i.text) for i in gml.xpath("//pt/z")]
        self.ts = [float(i.text) for i in gml.xpath("//pt/time")]
        self.length = len(self.xs)


class GmlDrawer(object):

    def __init__(self, gmlobj):
        self.gmlobj = gmlobj

    def set_canvas_size(self, x=640, y=480):
        self.canvas_x = x
        self.canvas_y = y
        self.canvas_size = (x, y)

    def draw(self, output_filename='test.png'):
        img = Image.new("RGB", self.canvas_size, (0, 0, 0))
        draw = ImageDraw.Draw(img)
        x = [(int(self.gmlobj.ys[i]/1.4*self.canvas_y),
              int(self.gmlobj.xs[i]/1.4*self.canvas_x)) \
                      for i in range(self.gmlobj.length)]
        draw.line(x, fill='rgb(255, 255, 255)', width=5)
        outimg = ImageOps.flip(img)
        outimg.save(output_filename)


def main():
    gmlobj = GmlObject('http://000000book.com/data/148.gml')
    gmldrawer = GmlDrawer(gmlobj)
    gmldrawer.set_canvas_size()
    gmldrawer.draw()

if __name__ == '__main__':
    main()

完成したもの

http://farm5.static.flickr.com/4072/4292262951_943a6a76d9.jpg

上記のようなPNG画像を出力できました。"hello world" って書いてます。

終わりに

GMLは奥行きと時間もデータとして保持しているのでアニメーションもさせたいところです。 面白そうな素材なので今後もウォッチしていこうかと。

では。