LoginSignup
5
4

More than 5 years have passed since last update.

SWF から全てのフィルターを削除する ActionScript

Posted at

無力なマクロ

コレは幻想です→「Adobe Flash の JSFL マクロを使えば、手作業が自動化できる!」

実際は、いくつかの操作は有効なマクロが存在せず、有効なはずのマクロですら実行したとたん頻繁に Adobe Flash がアドビクラッシュになり、その直後クラッシュデーモンが出現するのです。

Adobe 製品における正しい SWF の編集方法

Adobe Frustrator をはじめ、様々な Adobe 製品のクラッシュに悩まされ続ける皆さん。
もしあなたが .fla ファイルをマクロで操作している時にクラッシュしているのであれば朗報かもしれません。

出力される SWF ファイルのバイナリ編集方法は SWF から DoABC を削除する ActionScript で少し紹介しています。
今回は全てのフィルターを除去するツールを ActionScript で書く方法を紹介します。

swc を取ってくる

前回と同じく

https://github.com/claus/as3swf
http://github.com/claus/as3swf/blob/master/bin/as3swf.swc

コード

as3swf.swc を使って次のように書く

    import com.codeazur.as3swf.SWF;
    import com.codeazur.as3swf.data.SWFSymbol;
    import com.codeazur.as3swf.data.filters.IFilter;
    import com.codeazur.as3swf.tags.ITag;
    import com.codeazur.as3swf.tags.TagDoABC;
    import com.codeazur.as3swf.tags.TagPlaceObject3;

    // ...

        private function getAllTags(swf:SWF):Vector.<ITag>
        {
            var tags:Vector.<ITag> = swf.tags

            for each (var tag:ITag in swf.tags)
            {
                tags = tags.concat(getAllTagsFromTag(tag))
            }

            return tags
        }

        private function getAllTagsFromTag(parentTag:ITag):Vector.<ITag>
        {
            var tags:Vector.<ITag> = new Vector.<ITag>()

            if ((parentTag as Object).hasOwnProperty("tags"))
            {
                tags = parentTag["tags"]
                for each (var tag:ITag in parentTag["tags"])
                {
                    tags = tags.concat(getAllTagsFromTag(tag))
                }
            }

            return tags
        }

        public function removeFilters():void
        {
            var swfBytes:ByteArray = // SWF ファイルのバイト列
            var swf:SWF = new SWF(swfBytes)
            var filteredItems:Vector.<ITag> = getAllTags(swf).filter(
                function (item:ITag, index:int, array:*):Boolean
                {
                    return ((item as Object).hasOwnProperty("hasFilterList") && item["hasFilterList"] && item["surfaceFilterList"].length > 0)
                }
            )

            for each (var item:ITag in filteredItems)
            {
                while(Vector.<IFilter>(item['surfaceFilterList']).length != 0)
                    Vector.<IFilter>(item['surfaceFilterList']).pop()
            }

            var published:ByteArray = new ByteArray();
            swf.publish(published);
            // published をファイルに書きだしてね
        }

解説

  • getAllTags(swf) は SWF の内部に書かれたすべてのタグを取得
    • タグとはこういうもの→ 制御タグ
    • タグはツリー上のデータ構造になっている
  • removeFilters() では
    • as3swf を用いて全てのタグから hasFilterList を持つタグだけを抽出
    • それらのタグのフィルタ設定である surfaceFilterList の中身を空っぽに
    • 最後の publish はバイナリデータに書き戻したもの
    • ByteArray のpublished をファイルに書き出せば、そのファイルが「フィルタが全て削除された SWF」となる
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4