Photoshop用Javascriptでレイヤーマスクを作る方法

Photoshopを使ってると、複数のファイルに同じ処理を施したいことがある。多くは「アクション」を使えば目的が達成できるのだが、少し細かいことをしようとすると「アクション」では不十分なこともたまにある。そこで、Photoshop(に限らずAdobe製品の多く)は、Javascriptでアプリケーションを制御するスクリプトを作り、利用することができる。例えば、下記のスクリプトでキャンバスサイズを50pxずつ拡大できる。*1

activeDocument.resizeCanvas(activeDocument.width+50, activeDocument.height+50);

しかし、これも実は不十分で、例えば現在のレイヤーに現在の選択範囲を可視範囲とするレイヤーマスクを追加することができない。そこでよりローレベル(?)な方法を用いて、この足りない部分を実現させる必要がある。

インストールする

先の例で用いたAPIリファレンスを参照して地道に探していく必要があるのだが、APIで実現不可能なことを行う方法までは載っていないので、別の方法でこれを知る必要がある。具体的には、ScriptListenerを利用する。ScriptListenerは、Photoshopで行った動作をすべてJavascript(Winの場合、VBScriptも)で記録し、出力してくれるプラグインである。手順に従い、これをインストールして、Photoshopを再起動する。

記録させる

適当なファイルを開き、適当に選択範囲を作成、その後レイヤーパレットで「レイヤーマスクを追加」ボタンを押す。すると、この一連の動作がJavascriptとしてデスクトップに書き出される。必要な動作を記録させたら、すぐにPhotoshopを終了し、ScriptListenerをアンインストールしておこう。ScriptListenerはインストールされている間、常に「ON」の状態なので、普通に作業しているとそのログがすべて書き出される。つまり、処理的にもHDD的にも負荷が高くなってしまう。

確認する

デスクトップにある"ScriptingListenerJS.log"を開くと、なんかよくわからないコードがズラズラと書かれている。しかし、行った動作一つごとに区分けされて記録されてあるので、自分が行った動作を覚えていればどこでどんな動作を記録したのかは見つけやすい。ちなみに、今回の目的である「レイヤーマスクを追加」するスクリプトは下記のようになっていた。

var idMk = charIDToTypeID( "Mk  " );
    var desc14 = new ActionDescriptor();
    var idNw = charIDToTypeID( "Nw  " );
    var idChnl = charIDToTypeID( "Chnl" );
    desc14.putClass( idNw, idChnl );
    var idAt = charIDToTypeID( "At  " );
        var ref8 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idChnl = charIDToTypeID( "Chnl" );
        var idMsk = charIDToTypeID( "Msk " );
        ref8.putEnumerated( idChnl, idChnl, idMsk );
    desc14.putReference( idAt, ref8 );
    var idUsng = charIDToTypeID( "Usng" );
    var idUsrM = charIDToTypeID( "UsrM" );
    var idRvlS = charIDToTypeID( "RvlS" );
    desc14.putEnumerated( idUsng, idUsrM, idRvlS );
executeAction( idMk, desc14, DialogModes.NO );

レイヤーマスク一つ追加するためだけにこのコード量である。ActionDescriptor()やActionReference()など、それ自体に動作が定義されているわけじゃないメソッドを用いるため、そのインスタンスの設定が必要になっているようだ。charIDToTypeID()に渡されている4文字の文字列は、それが「行いたい動作」などを表すもののようだ。ただ、リファレンスにすら載っていない4文字もあるので、Adobeの本質が見えてくる気がする。ともかく、これを実行するとこで「現在の選択範囲でレイヤーマスクを追加する」ということができるのである。関数化しておけば、より使いやすくなるだろう。

まとめ

PhotoshopJavascriptAPIを用いるだけである程度のことはできる。しかし、それでもできないことは、ScriptListenerを利用してコードを教えてもらうしかない。ただ、APIにレイヤーマスクの透明度などを設定するプロパティがあるのに、肝心の「レイヤーマスクの追加する」メソッドがないのはどうしても解せなかった。

*1:具体的な実装方法、実行方法はAdobe Photoshop CS4自動化作戦を参照