無力なマクロ
コレは幻想です→「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」となる