[pukiwiki]
みなさまGWはいかがでしたでしょうか?
私はこんなことをして遊んでました(汗
—-
[[こちらの記事のつづきです:http://boxheadroom.com/2009/04/22/py_swfmill]]
[/pukiwiki]
[pukiwiki]
世の中にはLLからFlash(swf)を作成するための方法はいろいろあるのですけれども、今回は
-xmlを解釈してswfに変換してくれる[[swfmill:http://swfmill.org/]]というツールを使用。
-xmlを作成するためのユーティリティ関数をPythonで作成
と、ワンクッションおくことで、あたかもPythonでFlashを作成しているかのような作業環境を目指します。
つまりメインとしては”PythonでXMLを作成する”という話なのですけれども。
で、いきなり出来上がりのコード。
swfmillのsimpleモード用のラッパーです。
(swfmill.exeと同じフォルダで動かしてます)
[/pukiwiki]
import subprocess import xml.etree.ElementTree as etree import types class Tag(object): def __init__(self): self.builder=etree.TreeBuilder() def create(_self,tag,contents=[],attrs={}): class C(object): def __init__(self,contents=contents,attrs=attrs): self.attrs=attrs self.contents=contents def force(self): a={} for k in self.attrs: t=type(self.attrs[k]) if t in [ types.StringType,types.UnicodeType]: a[k]=self.attrs[k] else : a[k]=str(self.attrs[k]) _self.builder.start(tag,attrs=a) for i in self.contents: i.force() _self.builder.end(tag) C.__name__=tag return C def tostring(self): doctype="""<?xml version="1.0" encoding="utf-8" ?>\n""" ret=self.builder.close() return doctype+etree.tostring(ret) def reset(): global movie,background,clip,font,textfield,place,meta,frame,library tag=Tag() movie=tag.create("movie",attrs=dict(version="6",width=320 ,height=240,framerate=12)) background=tag.create("background",attrs=dict( color="#ffffff")) clip=tag.create("clip",attrs={ "id":"foo","import":"library/foo.jpg", "class":"org.osflash.Foo"}) font=tag.create("font",attrs={ "id":"vera", "import":"library/vera.ttf","glyphs":"0123456789"}) textfield=tag.create("textfield",attrs=dict( id="hellobox", width="200",height="50",size="10",font="vera",text="hello world!")) place=tag.create("place",attrs=dict(id="hellobox",name="output",depth="10")) meta=tag.create("meta",attrs=dict(title="my title",description="To be indexed")) frame,library=[tag.create(t) for t in "frame library".split()] if __name__=="__main__": root=movie(attrs=dict(framerate="10",height="200",width="400" ), contents=[ background(attrs=dict(color="#ffffff")), library([ clip(attrs={"import":"foo.jpg","id":"foo"}), textfield(attrs=dict( id="hello",text="hello world!", width="200",height="50",size="10")) ]), frame(contents=[ place(attrs=dict(depth=10,id="foo")), place(attrs=dict(depth=11,id="hello")) ]), ]) root.force() txt=tag.tostring() #print txt fname="helloworld" if True : proc = subprocess.Popen( #'swfmill.exe -v swf2xml niku.swf niku.xml', 'swfmill.exe -v simple stdin %s.swf'%fname, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, ) stdout_value = proc.communicate(txt)[0] stdout_value print stdout_value proc = subprocess.Popen( #'swfmill.exe -v swf2xml niku.swf niku.xml', 'swfmill.exe -v swf2xml %s %s'%(fname,fname), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, ) stdout_value = proc.communicate()[0] print stdout_value
以前の記事では遅延評価をデコレータとジェネレータを使って書きましたが、今回は素直にクラスを使いました。
実際にswfファイルの中身(を指定するためのXML)を記述しているのは以下の部分。
root=movie(attrs=dict(framerate="10",height="200",width="400" ), contents=[ background(attrs=dict(color="#ffffff")), library([ clip(attrs={"import":"foo.jpg","id":"foo"}), textfield(attrs=dict( id="hello",text="hello world!", width="200",height="50",size="10")) ]), frame(contents=[ place(attrs=dict(depth=10,id="foo")), place(attrs=dict(depth=11,id="hello")) ]), ]) root.force() txt=tag.tostring() #XMLが返って来る
内部的に作成されるXMLはこちら。
(適宜改行、インデントは手作業で加えました)
<?xml version="1.0" encoding="utf-8" ?> <movie framerate="10" height="200" width="400"> <background color="#ffffff" /> <library> <clip id="foo" import="foo.jpg" /> <textfield height="50" id="hello" size="10" text="hello world!" width="200" /> </library> <frame> <place depth="10" id="foo" /> <place depth="11" id="hello" /> </frame> </movie>
[pukiwiki]
こんな短いXMLを作るために、なんでこんな面倒なことを、、、と思われるかもしれませんが(自分でも思いますが)、IDLE使って書くと、普通にXMLを書き下すよりも楽でした。
ただし”simpleモード”だけだと、あまり使い道が無いので、細かいことをしたければ”xml2swfモード”用のラッパーを書かないといけないかも。
ActionScriptなどをいじろうと思うと、MTASCなどの助けも必要になりますし。
というわけで、 それらはまたいずれ。。。
*関数のキーワード引数に予約語を使うとシンタックスエラーになる
というのを、今回はじめて気が付きました。
dict(import=”spam.jpg”)
などとするとエラーになります。
{“import”:”spam.jpg”}
と書くことで回避できますけれども。
*関連記事
-[[PythonからswfmillでFlashムービー(swfファイル)を作成してみる:http://boxheadroom.com/2009/04/22/py_swfmill]]
-[[exec,eval とクロージャではまる&遅延評価:http://boxheadroom.com/2009/04/25/py_eval_exec_closure]]
—-
ToDo: ActionScript 、xml2swfモード
[/pukiwiki]