Hatena::ブログ(Diary)

なにする?DTP+WEB

2009-11-13

イラストレーターのスクリプトを高速化させるためのコツ

2つのスクリプトの速さの違いはどこにある。 - なにする?DTP+WEB

スクリプトの実行速度の違いに釈然としないままだったのですが。

Mr.Riさんより大変有用なサンプルを公開していただきました。

丁寧なコメント付ですごく参考になりました。

Mr.Riさんのページには便利なスクリプトが沢山公開されています。

Mr.Ri HomePage/ステレオ写真・山めしレシピ・DTPツール


そでれは、サンプルから解ったことを書いていこうとおもいます。

自分の書いたスクリプトが遅くて悩んでいる方必見ですよ。

イラストレーターのドキュメント中で、沢山のパスの中から0.3pt以下の線を抜き出すスクリプト

f:id:kamiseto:20091113214144p:image

普通に書くとこう書くと思う。

(function(){
var X = (new Date).getTime();
//-----------------------------------
var P = app.activeDocument.pathItems;//アクティブドキュメントのパスアイテム
var L = P.length; //パスの数
//
for(i=0; i<L; i++){
	CheckHearLine(P[i])
}

//渡されたパスが0.3pt以下なら選択状態にする
function CheckHearLine (PathObj){
	if( Math.round( PathObj.strokeWidth * 100 ) / 100 < 0.3  &&  ! PathObj.guides )PathObj.selected = true;
}
//-----------------------------------
var Y = (new Date).getTime();
alert(Y-X);
})();

結果はこんな感じ。

f:id:kamiseto:20091113214049p:image



こそで、爆速化サンプルを参考にレイヤー毎に処理していくことにする。

サンプルではサブレイヤーも処理していくのだけど今回は解り易く1階層のみレイヤー毎に処理するようにする。

(function(){
var X = (new Date).getTime();
//-----------------------------------

//
for(x=0; x < app.activeDocument.layers.length;x++){
var P = app.activeDocument.layers[x].pathItems;//レイヤーのパスアイテム
var L = P.length; //パスの数
for(i=0; i<L; i++){
	CheckHearLine(P[i])
}
}

//渡されたパスが0.3pt以下なら選択状態にする
function CheckHearLine (PathObj){
	if( Math.round( PathObj.strokeWidth * 100 ) / 100 < 0.3  &&  ! PathObj.guides )PathObj.selected = true;
}
//-----------------------------------
var Y = (new Date).getTime();
alert(Y-X);
})();

これだけでも十分な効果が得られます。

おお、スバラシィ〜。

f:id:kamiseto:20091113214129p:image

結果をふまえて、

スクリプトオブジェクトモデルを眺める。

f:id:kamiseto:20091113220619p:image

こういうことなのかな?

Mr.Riさんの解説ではイラストレーターだけではなくインデザインでも同じようなことが言えるそうです。

成る程。なるほど。

これをふまえて普段自分が使っているスクリプトに適用する。

いままで。

(function(){
var X = (new Date).getTime();
//-----------------------------------
#include 'c.js';
c('pathItems').each(CheckHearLine);
//渡されたパスが0.3pt以下なら選択状態にする
function CheckHearLine (PathObj){
	if( Math.round( PathObj.strokeWidth * 100 ) / 100 < 0.3  &&  ! PathObj.guides )PathObj.selected = true;
}
//-----------------------------------
var Y = (new Date).getTime();
alert(Y-X);
})();

f:id:kamiseto:20091113214324p:image


これから。

(function(){
var X = (new Date).getTime();
#include 'c.js';
//
c('layers').each(function(){c(this.pathItems).each(CheckHearLine)});
//渡されたパスが0.3pt以下なら選択状態にする
function CheckHearLine (PathObj){
	if( Math.round( PathObj.strokeWidth * 100 ) / 100 < 0.3  &&  ! PathObj.guides )PathObj.selected = true;
}
var Y = (new Date).getTime();
alert(Y-X);
})();

おお。

f:id:kamiseto:20091113214416p:image

これで、速度的にあきらめてたあんなことやこんなこともできるかもしれない。

ウホォォォォ。



理屈は良くわからないけど

こういう話も関係があったりするのかな?

一行で IE の JavaScript を高速化する方法 - IT戦記

Mr.RiMr.Ri 2009/11/15 07:17 上から二番目のスクリプト
var P = app.activeDocument.layers[x].pathItems;
var L = P.length;
for (i=0; i<L; i++) {CheckHearLine(P[i])}
これだとレイヤー上に直接あるパスしか選択されません。サブレイヤーのパスはサブレイヤーを呼び出してから、グループ化されているパスはグループを呼び出してから、複合パスのパスは複合パスを呼び出してから処理してください。サブグループも同じです。ご注意ください。

kamisetokamiseto 2009/11/15 09:10 Mt.Riさんどうもありがとうございます。
>>これだとレイヤー上に直接あるパスしか選択されません。
そこらへんは判っててやっております。w
1番目のスクリプトからいきなり2番目のスクリプトを再帰処理にもってくのはどうかと思ったので。
ありがちな、スクリプトやすでにあるスクリプトをどうすれば簡単に高速になるのかの例を出しました。
>>サブレイヤーのパスはサブレイヤーを呼び出してから、グループ化されているパスはグループを呼び出してから、複合パスのパスは複合パスを呼び出してから処理してください。サブグループも同じです。ご注意ください。
サブレイヤー、サブグループ、複合パスがある実戦向きの例でもやってみようと思います。
ありがとうございました。

Mr.RiMr.Ri 2009/11/15 10:28 判ってらしたんですね、よけいなこと書き込んですみません!
それからパスを選択する処理、これも数が多くなるとけっこう時間がかかるんですよね。
本日、ヘアラインレタッチ1.3をリリースしたんですけど、その中に爆速ヘアラインレタッチというのを追加しました。
実はこれ、pathObj.selected = true というのを削除しただけなんですよね。
ひどい手抜きですが、選択するパスの数(=ヘアラインの数)が多くなると本当に爆速ぶりを発揮します。
興味があったら試してくださいね。

kamisetokamiseto 2009/11/17 03:29 >>それからパスを選択する処理、これも数が多くなるとけっこう時間がかかるんですよね。
たしかに、数に比例してものずごく待たされることがあります。
selectedのtrue,false関係でいろいろ試しましたが、
劇的に速くなるような方法はなさそうです。
selectedをいじるスクリプトの場合、画面の拡大率が6400%と3%では6400%のほうが速くなります。
また、selectedを一個一個、true,falseするのではなく、
app.activeDocument.selection = Arrayとして、
Arrayを渡すと、多少速くなります。
ではでは。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/kamiseto/20091113/1258118098
ファイル名で示す規定値でオブジェクトを等間隔に分布するやつ
//id_distribute_=_0mm.jsx 2017.06.23(z-)ver_c //規定値で等間隔に分布する //規定値はスクリプトのファイル名で指定する //ファイル名は &qu
アートボードの任意の辺だけをオブジェクトに合わせる
//ai_artboard_fitter.jsx 2017.09.14(z-) ver_a //選択したオブジェクトにアートボードサイズを任意の辺だけ合わせる &nbsp; &nbsp
選択したひとかたまりごとに行/列の残り全部それぞれ結合していきます
//id_mergeEach.jsx 2017.01.31(z-) // ver_b 2017.06.28 処理範囲外に結合セルがあると動作不良が起きていたのを修正 &nbsp; var se
選択内の段落群を自動で手動インデントするやつのイラスター移植版
//ai_indentSetter.jsx 2017.06.21(z-) //選択内の段落群を自動で手動インデントするやつ //2017.06.21 ver_a &nbsp; #target
選択内の段落群を自動で手動インデントするやつ。既存値とのバッティ ...
//id_indentSetter.jsx 2017.06.19(z-) //選択内の段落群を自動で手動インデントするやつ //2017.06.19 ver_a &nbsp; #target
この日記のはてなブックマーク数