コピペからはじめるphotoshopスクリプト
2013/2/12
Tag: javascript,photoshop,script
別にはじめてじゃない気がするのですがとりあえずはじめまして、社内の軟体動物ことタコ(@takowasabi)です。
去年の9月に入社して以来、アニメーションチームのTDとして
使い慣れないmotionbuilder(以下MB)を相手に四苦八苦しております(´д`)
今回はMBではなくて自分的に馴染みのあるphotoshop(以下Ps)のツール作成について記事にしたいと思います。
[作業ログ出しツールでログを出してみよう]
softimageにしろmayaにしろ自分がした作業がログとして表示される機能がありますが、Psにも実はその機能があるのです。
そのやり方はadobeのhelpにこっそり載っていたり。
ScriptingListener プラグイン
PsCS6の場合、ScriptListener.8liをC:¥Program Files¥Adobe¥Adobe Photoshop CS6 (64 Bit)¥Plug-ins¥に置くと
Psでの作業に応じてデスクトップにScriptingListenerJS.logという名前の作業ログがテキスト形式で保存されます。
「ちゃんとScriptListener.8liをPlug-insフォルダに入れたのにScriptingListenerJS.logなんてもんデスクトップに無いぞー!」
って方は一度Psを終了させた後、再び立ち上げて新規のプロジェクト立ち上げるなりCtrl+Oで何か画像を開くなりしてください。
ScriptingListenerJS.logが生成されているかと思います。
今回はそのScriptingListenerJS.logを使用して今回は簡単なツールを作成してみたいと思います。
[ScriptingListenerJS.logを利用してコンテ切り抜きツールを作ろう]
Psの場合選択範囲の指定をスクリプトで最初から書くのは実は非常にめんどくさかったりするのですが、
ScriptListenerを使用すると選択範囲の指定そのものがログとして出るので非常に楽だったりするのです。
早速ScriptingListenerJS.logを使用してコンテの絵の部分だけを切り出して各々別に保存するツールを作成してみましょう。
[まずは手作業で行い、ログ出ししてみよう]
とりあえずログを用意する為に一連の手順を手作業でやってみましょう。
つまり、
選択ツールで絵の部分のみを囲う→コピー(Ctrl+C)→新規プロジェクトの作成(Ctrl+N)→作成した新規プロジェクトへペースト(Ctrl+V)→別名で保存、名前&ファイル形式は任意(Ctrl+shift+S)
の動作を手作業でするのです。
一連の作業を手作業で行なった後、デスクトップに作成されたScriptingListenerJS.logを開いてみましょう。
スラッシュ2つと破線で区切られてる区間に書かれてる呪文のような言葉、これが作業ログとなります。
softimageやmayaと比べると長ったらしいのですが、Psの場合複数行にわたって書かれてるコードで1つの動作を体現しています。
[Adobe ExtendScript Toolkitでコードを動かしてみよう]
adobe製品のスクリプトエディタ的役割のあるExtendScript Toolkitを使用して吐き出されたコードを動かしてみましょう。
adobe製品が何かしらインストールされていればExtendScript Toolkitはインストールされていると思いますが
んなもんねーよ!という方はadobeのサイトからダウンロードしておきましょう。 Adobe Scripting Center
そのままコピペして、実行すると先ほど手作業で行なった動作がスクリプトで自動化されてるかと思います。
先ほど吐き出されたログをベースに、コンテの絵を描く場所5コマ全て切り抜き、コンテのある場所に別名保存、その際の名前は元のコンテの名前+‐(ハイフン)+番号.jpg
というサンプルを書いてみました。
弊社のコンテ用紙をベースにしているのでほかのコンテで正しい動作を得たい場合、変数AddValueと関数Selecter()内の値を変更してもらえると正しく動作するかと思います。
また、見やすくするためにインデントつけときました。
function ConteScrap(){ for (var i=0;i<5;i++){ var AddValue= 151*i var DocName = activeDocument.fullName var SaveNo =i+1 var SaveName = DocName.toString().replace(".","-"+SaveNo+".") Selecter(AddValue) CopyContePicture() NewDocment () PaseteContePicture() SaveContePicture(SaveName) CloseDoc() } //選択範囲の指定 function Selecter(AddValue){ var idsetd = charIDToTypeID( "setd" ); var desc210 = new ActionDescriptor(); var idnull = charIDToTypeID( "null" ); var ref166 = new ActionReference(); var idChnl = charIDToTypeID( "Chnl" ); var idfsel = charIDToTypeID( "fsel" ); ref166.putProperty( idChnl, idfsel ); desc210.putReference( idnull, ref166 ); var idT = charIDToTypeID( "T " ); var desc211 = new ActionDescriptor(); var idTop = charIDToTypeID( "Top " ); var idRlt = charIDToTypeID( "#Rlt" ); desc211.putUnitDouble( idTop, idRlt,59+AddValue); var idLeft = charIDToTypeID( "Left" ); var idRlt = charIDToTypeID( "#Rlt" ); desc211.putUnitDouble( idLeft, idRlt, 170); var idBtom = charIDToTypeID( "Btom" ); var idRlt = charIDToTypeID( "#Rlt" ); desc211.putUnitDouble( idBtom, idRlt, 196+AddValue); var idRght = charIDToTypeID( "Rght" ); var idRlt = charIDToTypeID( "#Rlt" ); desc211.putUnitDouble( idRght, idRlt, 413); var idRctn = charIDToTypeID( "Rctn" ); desc210.putObject( idT, idRctn, desc211 ); executeAction( idsetd, desc210, DialogModes.NO ); } //選択範囲の絵をコピー function CopyContePicture(){ var idcopy = charIDToTypeID( "copy" ); executeAction( idcopy, undefined, DialogModes.NO ); } //新規ドキュメントを作成 function NewDocment (){ var idMk = charIDToTypeID( "Mk " ); var desc213 = new ActionDescriptor(); var idNw = charIDToTypeID( "Nw " ); var desc214 = new ActionDescriptor(); var idpreset = stringIDToTypeID( "preset" ); desc214.putString( idpreset, "クリップボード" ); var idDcmn = charIDToTypeID( "Dcmn" ); desc213.putObject( idNw, idDcmn, desc214 ); executeAction( idMk, desc213, DialogModes.NO ); } //ペースト function PaseteContePicture(){ var idpast = charIDToTypeID( "past" ); var desc215 = new ActionDescriptor(); var idAntA = charIDToTypeID( "AntA" ); var idAnnt = charIDToTypeID( "Annt" ); var idAnno = charIDToTypeID( "Anno" ); desc215.putEnumerated( idAntA, idAnnt, idAnno ); executeAction( idpast, desc215, DialogModes.NO ); } //選択範囲の解除 function RemoveSelection (){ var idsetd = charIDToTypeID( "setd" ); var desc243 = new ActionDescriptor(); var idnull = charIDToTypeID( "null" ); var ref182 = new ActionReference(); var idChnl = charIDToTypeID( "Chnl" ); var idfsel = charIDToTypeID( "fsel" ); ref182.putProperty( idChnl, idfsel ); desc243.putReference( idnull, ref182 ); var idT = charIDToTypeID( "T " ); var idOrdn = charIDToTypeID( "Ordn" ); var idNone = charIDToTypeID( "None" ); desc243.putEnumerated( idT, idOrdn, idNone ); executeAction( idsetd, desc243, DialogModes.NO ); } //jpegで名前をつけて保存 function SaveContePicture(SaveName){ var idsave = charIDToTypeID( "save" ); var desc254 = new ActionDescriptor(); var idAs = charIDToTypeID( "As " ); var desc255 = new ActionDescriptor(); var idEQlt = charIDToTypeID( "EQlt" ); desc255.putInteger( idEQlt, 12 ); var idMttC = charIDToTypeID( "MttC" ); var idMttC = charIDToTypeID( "MttC" ); var idNone = charIDToTypeID( "None" ); desc255.putEnumerated( idMttC, idMttC, idNone ); var idJPEG = charIDToTypeID( "JPEG" ); desc254.putObject( idAs, idJPEG, desc255 ); var idIn = charIDToTypeID( "In " ); desc254.putPath( idIn, new File(SaveName) ); var idCpy = charIDToTypeID( "Cpy " ); desc254.putBoolean( idCpy, true ); executeAction( idsave, desc254, DialogModes.NO ); } //コピペ先のドキュメントを閉じるよ function CloseDoc (){ var idCls = charIDToTypeID( "Cls " ); var desc275 = new ActionDescriptor(); var idSvng = charIDToTypeID( "Svng" ); var idYsN = charIDToTypeID( "YsN " ); var idN = charIDToTypeID( "N " ); desc275.putEnumerated( idSvng, idYsN, idN ); executeAction( idCls, desc275, DialogModes.NO ); } } ConteScrap()
[通常のスクリプトでは不可能なことでもScriptingListenerJS.logで出来るようになるよ!]
スクリプティングをかじったことのある方なら、「こんな単調で長ったらしいコードどういう時に役に立つねん」と思うかもしれません。
実はコレ、ScriptingGuideに載っていない&不可能な作業も可能としてくれるのですよ!ワーイ
以前私のblogでも触れましたが、レイヤーを複数(飛び飛び)選択するとかレイヤー効果の追加なんかもまるっとコピペで出来るようになります。
あとあれですね、コピペだしイチからScriptingGuide読んでチクチク書くよりかはずっと精神的なハードルが低いかと思います、気楽!
やー、これAfterEffectsにも欲しいですね!コピペ!
※免責事項※
本記事内で公開している全てのコードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任で使ってね☆
コメント
コメントフォーム