※この問題はバージョン18.0(AE2021)以降で修正されました。
var v = Number(app.version.match(/^\d+\.\d/));
if (17.0 <= v && v <= 17.99) {
//2020用
} else {
//その他バージョン用
}...
等のようにして、バージョンを判断して振り分ける必要があります。
AECC2020でレイヤーに適用されたエフェクトの名前を取得するのは問題ないのですが、
(function(){
$.writeln(app.project.item(1).layer(1).effect(1).matchName)
$.writeln(app.project.item(1).layer(1).effect(1).name)
})()
実行結果
ADBE Fractal Noise
フラクタルノイズ
app.effectsでエフェクト情報を取得すると問題が。
app.effects配列1にはインストールされているエフェクト情報2のオブジェクトが入っているのですが
AECC2020では、このオブジェクトの値にマルチバイト文字があると文字化けしてしまいます。
(function() {
var effects = app.effects; // app.effectsは毎時実行せずに一旦変数に代入すると速い
var count = effects.length;
for (var i = 0; i < count; i++) {
var effect = effects[i];
if (effect.matchName === 'ADBE Fractal Noise') {
$.writeln(effect.toSource());
break;
}
}
})()
CC2020の結果
({displayName:"テtテノテNテ^テヒテmテCテY", matchName:"ADBE Fractal Noise", category:"テmテCテYチユテOテフテCテモ", version:"17.1"})
CC2019の結果
({displayName:"フラクタルノイズ", matchName:"ADBE Fractal Noise", category:"ノイズ&グレイン", version:"16.1.3"})
キー | 説明 |
---|---|
displayName | メニューにも表示される、エフェクトのデフォルト名 |
matchName | エフェクトのユニークな名前 (ASCII文字) |
category | メニューのグループ名 |
version | エフェクト作成者が付けた任意の値 |
これが地味に不便で、例えばプロジェクトファイル上で使用されているエフェクト一覧を表示するスクリプトを作成しようとすると、文字化けした一覧を表示してしまいます。
レイヤーのエフェクト名は文字化けしないのだから問題ないのではと思われますが、適用されたエフェクトの名前はユーザーが任意に変更できるので、エフェクトのデフォルト名は、適用されたエフェクトのmatchNameを利用して、app.effects配列のオブジェクトからdisplayNameを取得しなくてはなりません。
そもそもapp.effectsという配列自体が使いにくいので、通常そのようなスクリプトを作成するにあたっては、ユニークな値であるmatchNameをキーとした辞書をあらかじめ作成するのがよいと思います。
(function() {
var effects = app.effects;
var count = effects.length;
var effect_dict = {};
for (var i = 0; i < count; i++) {
var effect = effects[i];
effect_dict[effect.matchName] = effect;
};
//matchNameのキーでアクセス出来る辞書を作ると便利
$.writeln(effect_dict['ADBE Fractal Noise'].toSource());
})()
さて文字化けについてですが、どうもエンコードがおかしいみたいなので修正すればよさそうなのですが、ここはいまだES3規格のExtendScript。文字コードライブラリを使うのも書くのめんどいと思ったところ、なんとこの文字化けした文字列、バイナリで保存してsjisで読み込むと復元できるではありませんか。
どうせ辞書を作るのなら、バイナリで保存して復元して辞書を作るのも手間なので、バイナリとしてjsonを書き出してからJSON.parseすれば簡単なのでは!
ところでJSONのライブラリはどうするのかと思われますが、実はAECC2015から、AEのインストールフォルダに予め用意されているので今回はこれを利用しようと思います。
(function() {
// AEのインストールフォルダにあるjson2.jsxを利用する
var lib = Folder.appPackage.fsName + '/Libraries/jsx/'
$.evalFile(new File(lib + 'json2.jsx'));
var effects = app.effects;
var count = effects.length;
var effect_dict = {};
var tmp = new File(Folder.temp.fsName + '/__effects_dict__.txt');
tmp.encoding = 'BINARY';
tmp.open('w');
// jsonを作る。JSON.stringifyはstringになってしまうので使用できない
tmp.writeln('{');
for (var i = 0; i < count; i++) {
var effect = effects[i];
var key = effect.matchName;
var data = '"' + key + '": {'
data += '"displayName": "' + effect.displayName + '",';
data += '"matchName": "' + effect.matchName + '",';
data += '"category": "' + effect.category + '",';
data += '"version": "' + effect.version + '"},';
tmp.writeln(data);
}
tmp.writeln('}');
tmp.close();
tmp.encoding = 'sjis';
tmp.open('r');
var decoded_data = tmp.read();
tmp.close();
tmp.remove();
effect_dict = JSON.parse(decoded_data);
$.writeln(effect_dict['ADBE Fractal Noise'].toSource());
})()
CC2020での実行結果
({displayName:"フラクタルノイズ", matchName:"ADBE Fractal Noise", category:"ノイズ&グレイン", version:"17.1"})
辞書のキーに空白などが含まれるのですが、とりあえずは問題なく動作しているのでこれでいいかなと。心配ならFolder.encode等を使用するといいかもしれません。
あとはバージョンによって2つのコードを使い分けるようにすればいいでしょう。
現状結構速度もそこそこ速く簡単なので、これでいいかなといった感じです。もっと良い方法がある、このライブラリ使えるかも等ありましたら教えて頂けたらと思います。
ちなみにこのバグ?全然修正されないんですよね......