swfreplacepng.php

SWF の PNG 入れ替えを PHP だけで処理してみました。

原理

  • PHP の GD ライブラリで PNG データをピクセル形式で取り出す
  • 透明ピクセルが無ければ DefineBitsLossles 。もしあれば、DefineBitsLossless2 のフォーマットで格納する。
  • パレット形式は format = 3 で、トゥルーカラー形式は format=5 のフォーマットに従う。
  • 注意点
    • RGB(24bit)のパレット形式では横のライン毎に 4byte 境界に合うように padding を入れる。
    • A(alpha値)は GD は0(不透明)〜127(透明)で、SWF では 0(透明)〜255(不透明)なので、変換する。
    • ARGB, RGBA 表現は、A に応じて RGB を補正する。(R' = R * A / 255) みたいに。

上記のようにバイナリを構築して、SWF 内の画像タグを差し替える。

実験

  • 対象 SWF

http://diary.awm.jp/~yoya/data/2010/11/17/saitama.swf

  • 差し込みたい画像

http://diary.awm.jp/~yoya/data/2010/11/17/littleyoya_pink_h.png

(Openpear の IO_Bit, IO_SWF がインストールされてる前提で)
% php swfreplacepng.php saitama.swf 1 littleyoya_pink_h.png  > ~/littleyoya_pink_h.swf
  • 結果

http://diary.awm.jp/~yoya/data/2010/11/17/littleyoya_pink_h.swf

枠に収まりきらず画像の左上の方だけ表示されてますが、とりあえず成功。

その他

  • Openpear IO_Bit, IO_SWF は以下のコマンドでインストール出来ます。
pear channel-discover openpear.org
pear install openpear/IO_Bit
pear install openpear/IO_SWF
  • パレット形式で透明度がついてるケースは、GD の対応次第ですが、動くのか今のところ謎です。
  • パレット形式のカラーマップ RGBA。仕様書からは A補正が要らないように読み取れますが、補正しないとダメっぽいです。(実際試して補正が必要でした)

近いうちに @yoyapp さんが図付きで丁寧に説明してくれると思います。