PythonからswfmillでFlashムービー(swfファイル)を作成してみる

マジンガーZが空を飛べたらなぁ Pythonの標準ライブラリにMingが入ってたらなぁ

以前購入したFlashMXも、Vistaでは動かないらしいですし(未確認)
、、、などとグチっててもしょうがないので、Pythonからswfmill.exeにデータを渡して、Flashムービー(swfファイル)を作成してみます。

作成してみたサンプルFlashムービー

先にFlashムービー(swfファイル)をプログラム言語から作成したいときのまとめ。
まだまだ、いっぱいありますけど、今回のに直接関係してる分だけ。

Pythonからswfmill.exeにxmlデータを渡して、Flashムービー(swfファイル)を作成してみます。

できれば、標準ライブラリに含めてもらえるとうれしいです。めったに使わない、といえば、それはそうなのですけれども。

  • DrawSWF
    手書きイラストを、描いた順番を再現するアニメーションにしてくれるjavaアプリケーション
    サンプル
  • swfmill
    swfを解析してxmlに、またはその逆を行ってくれるソフト。
    今回のpythonプログラムと同じフォルダにswfmill.exeを解凍しておいてください。というか、無いと動きません。

とりあえず、線の座標を渡して、順番に線を表示していくプログラム。
DrawSWFで作成したswfファイルを雛形にして、値を書き換えるだけ。
(今回は、10角形の辺、  そして、中心と頂点を結んでみます)
タートルグラフィックなんかと組み合わせると楽しそう。

最初、ElementTreeをつかって元データとなるXMLを作成しようとしたのですが、よくわからなくなったので、まずは原始的でワイルドな方法から。
もっとクールに書く方法はないかしらん?

"linetest.py"
import math
import subprocess

twip=20
W,H=640*twip,480*twip

swf_header="""<?xml version="1.0"?>
<swf version="4" compressed="0">
  <Header framerate="20" frames="2">
    <size>
      <Rectangle left="0" right="%(W)s" top="0" bottom="%(H)s"/>
    </size>
    <tags>
      <SetBackgroundColor>
        <color>
          <Color red="255" green="255" blue="255"/>
        </color>
      </SetBackgroundColor>
"""

line_header="""      <DefineShape3 objectID="%(objectid)s">
        <bounds>
          <Rectangle left="%(bx0)s" right="%(bx1)s" top="%(by0)s" bottom="%(by1)s"/>
        </bounds>
        <styles>
          <StyleList>
            <fillStyles/>
            <lineStyles>
              <LineStyle width="1">
                <color>
                  <Color red="%(pen_r)s" green="%(pen_r)s" blue="%(pen_r)s" alpha="255"/>
                </color>
              </LineStyle>
            </lineStyles>
          </StyleList>
        </styles>
        <shapes>
          <Shape>
            <edges>
"""
line_point0="""              <ShapeSetup x="%(pen_x0)s" y="%(pen_y0)s" lineStyle="%(pen_thick)s"/>\n"""
line_point1="""              <LineTo x="%(pen_x1)s" y="%(pen_y1)s"/>\n"""
line_footer="""
              <ShapeSetup/>
            </edges>
          </Shape>
        </shapes>
      </DefineShape3>
      <PlaceObject2 replace="0" depth="%(objectid)s" objectID="%(objectid)s">
        <transform>
          <Transform transX="0" transY="0"/>
        </transform>
      </PlaceObject2>
      <ShowFrame/>
"""      

showframe="      <ShowFrame/>\n"

swf_footer="""      <DoAction>
        <actions>
          <Stop/>
          <EndAction/>
        </actions>
      </DoAction>
      <ShowFrame/>

      <End/>
    </tags>
  </Header>
</swf>
"""
txt=""

r=H/3

ox,oy=W//2,H//2
line=[[int(r*math.sin(2*(t/10.)*math.pi))+ox,
       int(-r*math.cos(2*(t/10.)*math.pi))+oy]  for t in xrange(10+1)]

pen_r,pen_g,pen_b=(0,0,0)
txt+=swf_header%locals()
pen_thick=1
lastx,lasty=line[0]
objectid=0
if True :
 for x,y in line[1:]:

    bx0,by0=min(lastx-1,x-1),min(lasty-1,y-1)
    bx1,by1=max(lastx+1,x+1),max(lasty+1,y+1)
    txt+=line_header%locals()
    txt+=line_point0%dict(pen_x0=lastx,pen_y0=lasty,pen_thick=1)

    txt+=line_point1%dict(pen_x1=x-lastx,pen_y1=y-lasty)
    txt+=line_footer%locals()
    txt+=showframe*5
    lastx=x
    lasty=y
    objectid+=1

p0=line_point0%dict(pen_x0=ox,pen_y0=oy,pen_thick=1)
txt+="<!--  -->\n"
objectid+=1
if True :
 for x,y in line[:-1]:
    bx0,by0=min(ox-10,x-10),min(oy-10,y-10)
    bx1,by1=max(ox+10,x+10),max(oy+10,y+10)
    txt+=line_header%locals()
    txt+=p0
    txt+=line_point1%dict(pen_x1=x-ox,pen_y1=y-oy)
    txt+=line_footer%locals()
    txt+=showframe*5
    objectid+=1

txt+=swf_footer
fp=open("test.xml","w")
fp.write(txt)
fp.close()

proc = subprocess.Popen(
                        #'swfmill.exe xml2swf stdin test.swf',
                        'swfmill.exe xml2swf stdin stdout',
                       shell=True,
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,

                       )
stdout_value = proc.communicate(txt)[0]
fp=open("test.swf","wb")
fp.write(stdout_value)
fp.close()
Tags:

Related posts

Tags:

Comments are closed.