preload
5月 08

前回までの「ケータイサイトでFlashLiteコンテンツを動的生成する」エントリで紹介してきた swfmill を使った FlashLite コンテンツの動的処理に関連して、SWF に含まれる画像やテキストを操作するための簡単なクラス集を作ってみました。

swfmill_ruby – github

swfmill と同じ GPL2(the GNU GENERAL PUBLIC LICENSE Version 2) にてライセンスいたします。

swfmill_ruby は、Swfmill を ruby から起動するための簡単なクラス(SwfmillUtil::Swfmill)と、これを使って Swf を操作するためのクラス(SwfmillUtil::Swf)から構成されます。使用には、ruby の標準的な開発環境に加えて、以下のものを用意する必要があります。

その他、使用手順など、詳細は公開ファイル中の README を参照してください。

Swf の操作機能は、現時点では、もっともよく利用する:

  • 画像の入れ替え
  • テキストの入れ替え

に絞って実装しています。これを使用することで、以下のサンプルコードのように、Swf#images で Swf 中の画像データを objectID => Magick::Image のハッシュ、Swf#texts でテキストデータを objectID => String のハッシュにてアクセスする事ができます。

require '../lib/swfmill_util'
require 'pp'

# initialize
swf = SwfmillUtil::Swf.new(File.open("sample.swf").read)

# check included images (object_id => Magick::Image)
pp swf.images #=> {"6"=> JPEG 176x208 176x208+0+0 DirectClass 8-bit 10kb, "3"=>  30x30 DirectClass 16-bit}
pp swf.texts #=> {"2"=>"343201202343201204343201206343201210343201212ABCr"}

# write included images
#swf.images.each do |i,image|
#  image.write("#{i}.#{image.format ? "jpg" : "gif"}")
#end

# replace included images
swf.images['3'] = Magick::Image.from_blob(File.open("flymelongirl.gif").read).first
swf.images['6'] = Magick::Image.from_blob(File.open("bg.jpg").read).first
swf.texts['2'] = "かきくけこXYZ"

# write swf replaced images
swf.write("foo.swf")

後半で書いている通り、画像やテキストの書き換えは、ハッシュの値を置き換えてやる事で実現できます。Swf#write によりファイル出力できますし、Swf#regenerate で再生成後の swf をそのまま得る事もできます。

内部的には、Magick::Image <=> DefineBitsJPEG2/DefineBitsLossless2 の変換をおこなっています。とくに DefineBitsLossless2 の変換処理は、ちょっと面倒ですし、あまり ruby での実装を見かけないので、何らか使いどころがあればお使いください。ImageMagick / RMagick を併用するので多少重たいかもですけど。

なお、FlashLite 1.1 を対象に、よく使うあたりを中心に実装していますので、DefineBitsJPEG3 や DefineBitsLossless2 での format=5, DefineBitsLossless, DefineText などはひとまず除外しています。必要に応じて、適当に修正してみてくださいませ。

今更ながら、大胆な名付けをしてしまった気がするので、いろいろいじってみてもらえると嬉しいです!

関連していそうなエントリ:

4 Responses to “SwfmillでFlashLite用SWFの画像やテキストを操作するRubyライブラリ SwfmillRuby”

  1. muraoka17 Says:

    こんにちは、便利なライブラリありがとうございます。
    動作検証していたところ、SwfmillUtil::DefineBitsLossless2.(image2xml|xml2image) で 4byte アラインメントの処理に不具合があるようです。4 – (幅 % 4) ですと、幅がちょうど 4の倍数の場合にも、4バイト分 0パディング(or 読み飛ばし)してしまいます。4 – 幅 & 3 が正しいように思われますがいかがでしょうか。

  2. tmtysk Says:

    muraoka17さん、動作検証ならびにコメントありがとうございます!
    ご指摘の件ですが、確かにその通りですね.. 大変失礼しました。
    修正しておきます。
    ありがとうございました!

  3. k2o Says:

    はじめまして。
    上の方と同じ、パディングのところですが、image.rowsを使っていますが、
    幅なので、image.columnsではないでしょうか。

  4. admin Says:

    k2oさん、はじめまして。
    ご連絡ありがとうございます。
    体調を崩しており、お返事が遅くなってしまってすみません。
    おっしゃるとおり、padding処理が間違っていましたので修正しました。
    私がテストに正方形の画像を使用していたのが不適切でしたね..
    あまりメンテナンスできていなくてご迷惑をおかけしますが、
    今後ともよろしくお願いいたします!