[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]