Photoshop UXP 2022 BatchPlay descriptors,プロパティーの取得等
Photoshop UXP 2022の公式ドキュメントのbatchPlayのページに中身の説明が大幅に追加されました。今回このドキュメントに書かれている事を中心に取り上げたいと思います。(今回公式で説明されている事をほとんど日本語で説明するだけ)
そもそもbatchPlayとは
過去の記事で詳しく説明していますがApi経由でなく直接Photoshopに特定の処理の実行を命令できるメソッドです。今までよく分かってなかったのですが今回公式のドキュメントである程度突っ込んで書かれているので実際に簡単に試してまとめてみました。
descriptors
batchPlayメソッドには行くとかのオブジェクトを引数として渡すのでが主なobjectがこのdescriptorsと呼ばれるものです。具体的には以下のようになっています。
このdescriptorsの中身でbatchPlayの実行内容がほとんど決まります。Array型になっているのは連続して異なる内容を実行できるようにするためです。optionは同期、非同期等のoptionになります。このdescriptors形式のオブジェクトはactionJSONとも言われる事があるみたいです。具体的にdescriptorsの中身のaction descriptorの具体的な役割として以下のようになります。
-
command
コマンドと呼ばれるものがPhotoshopの動作の説明、命令になります。このコマンドは_objキーの値になります。
-
target
コマンドのターゲット(対象はdocumentとかlayer等)。これはPhotoshopUXPのDOMを元に実行されます。このターゲットは_targetキーの値として渡します。このプロパティーは省略できることもあります。省略された場合のターゲットは大体アクティブな状態のものがターゲットになります。
-
parameters
コマンドのためのパラメーター。特定のbatchPlayを実行するために必要なパラメーターなどです。
-
options
batchPlayをどのように実行するかを定義するオプション。恐らく深い理由でもない限りデフォルトのままで良いと思われる。
おそらく上記の説明を見てもいまいちしっくりこないと思います。なので以下、具体的に見ていきます。
これはアクティブなレイヤーの表示を非表示にするコマンドです。_objのキーに実行内容、targetの配列内にターゲットととなるオブジェクトモデルを指定しています。例えば{“_ref”:”document”, “_enum”:”ordinal”,”_value”:”targetEnum”}というのはアクティブなドキュメンをターゲットにしています。_refキーにDOMのプロパティーを値として渡します。”_enum”:”ordinal”,”_value”:”targetEnum”でアクティブな要素をターゲットにするようです。なので今回はアクティブなドキュメントをターゲットにします。さらに{_ref: “layer”, _enum: “ordinal”, _value: “targetEnum”}というオブジェクトが格納されています。これは_refがlayerになっているのでわかる通りアクティブなレイヤーをターゲットにしています。以上でアクティブなドキュメントのアクティブなレイヤーをターゲットにしたコマンドです。後々説明しますがもちろんそのたindexでの選択、プロパティーを指定してのターゲットの選択もできます。_objの命令内容がhideになっています。つまりアクティブなドキュメントのアクティブなレイヤーを隠すという命令ですね。ドキュメントを読む限りこれらの要素はApiのDOMに基づいているらしいので(ドキュメント->レイヤーのように)大体このターゲット名は想像はつくのではないのでしょうか。例えばApi経由で同じような処理を実行する場合以下のようになります。
次に特定の画像の箇所のピクセルの情報を読み込むコマンドです。
カラーサンプルを読み込むコマンドのsamplePointに対して読み込むピクセルの位置をコマンドパラメーターとして渡すことでその位置の読み込みができます。以下のような値が返ってきます。
とはいえ具体的にどのようなコマンドがあってどのようなパラメーターを渡せばいいかよくわからないと思いますし実際ドキュメントこれらの情報がまとめられている訳ではありません。ただしPhotoshopには既にいくつかScriptListenerのような機能がデフォルトで搭載されているのでこれを使えばScriptListenerと同じような使い方でbatchPlayのコマンドを取得できます。それらの機能についていくつか紹介します。
addNotificationListener
UXPのevent機能を使用してユーザーのPhotoshop上のアクション毎にアクションの内容をactionJSONとして返します。コードとしては以下のようになります。
addNotificationListenerはPhotoshop内でのイベントを登録するメソッドでaddEventListenerのようなメソッドです。イベントの種類allはあらゆる種類のイベントを登録、アクションが起きた時にコールバックでevent,descriptorとして返ってきます。これをconsoleで表示するとデバックウインドウにactionJSONとして表示します。
actionJSONが表示されています。レイヤーを移動、選択範囲の作成等ユーザーが何かしらPhotoshop上で動作を行うとその動作に関連したactionJSONを表示します。警告が何か出ていますがallというイベントに対して警告しています。allというイベントは本番環境では使わない方が良いということでしょう。
アクション コマンドを記録
これはほとんどまんまScriptListenerのUXPバージョンですね。上のアクションコマンドを記録メニューボタンを押すと保存ダイアログが出てきます。jsonを保存するディレクトリーを指定後にPhotoshop上で何かしら動作を実行するとそれに対応したactionJSONを書き出します。
このように書き出されました。直ぐにbatchPlayに流用できそうですね。アクション通知コマンドを記録とアクションコマンドを記録と二種類ありますがアクションコマンドを記録が動作の内容だけをactionJSONに書き出すのに対してアクション通知コマンドを記はヒストリーの状態も含めて記録されていました。恐らくPhotoshop上のドキュメント等の状態の変化も含めて記録するのでしょうか?
アクションをactionJSONとして保存
PhotoshopのアクションセットにはPhotoshop上の動作が記録されていますがこれをそのままactionJSONとして書き出せます。macの場合shift+option+command、winの場合shift+control+altを押しながらアクションの保存を選択するとアクションの内容をactionJSONとして書き出してくれます。
ただここまで説明してなんですが過去の記事でも説明した通りにactionJSONを取得するためならデフォルトの機能よりもalchemistというUXPプラグインを使った方が効率がいいでしょう。
options
batchPlayメソッドの二つ目の引数にオプションオブジェクトを渡せます。同期、非同期、ヒストリーの表示名などを管理できるらしいのですが恐らくここの値は常にデフォルトの値のままで良いでしょう。ヒストリー関係の管理はPhotoshop2022以降はPhotoshopCoreモジュールから行うようドキュメントでも勧められています。こちらの記事を参照。
実行後の結果の値
batchPlay実行後に非同期で(Promise)を返します。もちろんエラーも返しますがエラー、rejectはbatchPlay、actionJSONに無効な値を返した時rejectします。それ以外にターゲットとなるドキュメントがない、レイヤーがないといった時はrejectせずそのままresolveしてメッセージとして実行できなかった理由を表示します。
なのでエラーの扱いには注意してください。
state(ドキュメントなどの状態の値)を取得する
batchPlayからもApiのようにドキュメント、レイヤー等のプロパティーを取得できます。コマンドの記述はPhotoshopのアクションの実行と似たような感じです。
_objキーの値、コマンド名がget,プロパティーを取得するのでそのまんまですね。ターゲットはapplication内のドキュメント、Apiでいうところのapp.documentsのような感じですね。今回idを指定してドキュメントを選択しています。もちろんidだけでなくnameやindexでも選べます。最後に_propertyで取得したいプロパティー名を渡します。これでドキュメントのタイトルを取得できます。プロパティーは省略するとターゲットのオブジェクトの全てのプロパティーが取得できます。
Api経由で取得した場合とまた取得できるプロパティーが異なります。(EXIF等Api経由だと取得できない)公式のドキュメントでは指定する条件としてはidを一番勧めています。UXPはdocument,layerといったあらゆる要素がidを持っています。このidは他のプロパティーと違ってPhotoshopが閉じるまでの間保持されるので特定のドキュメントを選ぶ時等確実に思った通りの対象をターゲットにしてくれます。これに対してindex,name等はPhotoshopが動いている時に変わってします可能性があります(勿論意図して使う場合は別)。
Multi-Get
Multi-Getは複数のドキュメントからプロパティーを取得する時、複数のプロパティーを同じターゲットから取得したい時に使います。以下のように取得できます。
これはアクテブドキュメントのアクティブなレイヤーから”name”, “layerID”, “opacity”のプロパティーを取得するコードです。_objのコマンドがmultigetになりましたしそれ以外に見慣れないオブジェクトが記述が出てきました。以下詳細。
extendedReference
Array型で値を渡します。一つ目の配列には取得したいプロパティー名を配列で渡します。二つ目には取得したいindexの開始numberと取得したい範囲をオブジェクトで渡します。
options
取得したプロパティーがなかった時などにどのように反応すべきか定義するオプションです。
failOnMissingProperty
failOnMissingPropertyは指定のプロパティーが存在しなかった場合のbatchPlayの反応を定義します(boolean)。falseの場合は見つからなかった場合はそのままスルーします。指定したプロパティーが全く見つからなかった場合は空のオブジェクトを返します。trueにすると不明なプロパティーが一つでも見つかると取得処理は失敗したとみなして失敗したメッセージのみを返してプロパティーの検索をやめます。デフォルトはtrueです。
failOnMissingElement
failOnMissingElementはターゲットとなるオブジェクト要素がなかった場合のbatchPlayの振る舞いを定義します(boolean)。falseの場合見つからなかった場合はそのままスルーして空のオブジェクトを返したりします。trueの場合は取得処理は失敗したとみなして失敗したメッセージのみを返します。デフォルトはtrueです。
その他複数のオブジェクトを取得してみます。
今回_target内のdocumentとは別にextendedReferenceに取得したいプロパティーとは別にオブジェクトが渡されています。この中の_objキーのレイヤーは対象がレイヤーになるのはわかります。indexはArrayのindexと同じです。レイヤーやチャンネルといったArray型の配列として取得できる要素のindexになります。countはindexからいくつの数のオブジェクトを取得するかの数値です。index:1, count:2の場合は一番下のレイヤーから二つのレイヤーオブジェクトを取得します。ただしArray型と違ってindexは0からでなく1からになるので注意してください。上のレイヤーをApiに直すと以下のようになります。
実際batchPlayの場合下からレイヤーを取得するのに対してApiの場合は上からレイヤーを取得するので全く同じようなコードにする場合layers.lenghtからindexを引かないといけませんがあくまで似たように書き直すと上のようになるという例です。
全ての配列のオブジェクトを取得したい場合は下記ようにcountを-1にすると全てのオブジェクトを取得できます。
一部の処理、値の取得はApi経由で行うよりもbatchPlayの方が早く行ってくれるようです。まだまだ不明点も多いですが当分batchPlay抜きにUXPの開発は難しそうです。