Photoshop関連ツールの運用を改善した話 Now In REALITY Tech #128
アバターシステムチーム エンジニアのうっちーです。
REALITYでは衣装などの制作でPhotoshopを使用しています。
Photoshopではスクリプト等を用いてを記載することで作業の効率化を図ることができます。
最近、制作ツールの使いやすさを向上させるため、Photoshopのツール運用を見直しました。この記事では、その改善内容と背景についてご紹介します。
これまでの運用
ツールの管理
Photoshopのツールに関するものはほかのプロダクトとまとめて管理されていました。理由としては、1つの開発チームがまとめてツールを開発しており、フォルダ構成としても他プロダクトツールと合同の1つのツールとして扱われてました。
# これまでのフォルダ構成
tools/
└ adobe/
├ action/
│ ├ reality/
│ │ └ 提供している.atn
│ └ 他プロダクト用フォルダ/
└ jsx/
├ reality/
│ └ 実際に実行される.jsx
└ 他プロダクト用フォルダ/
ツールの管理していくうえでの課題
このツール管理の仕方だとツールをまとめて開発しているチームとREALITYが離れていたため、機能を追加する際は開発しているチームにコードのレビューや依頼が必要であり、開発する上でも他プロダクトへの影響を考慮して実装する必要があったため、1機能を作る上でのコストが高いという課題がありました。
ツールの提供形態
Photoshopのツールの提供形態としてはアクションの提供です。
アクションとは、Photoshop での一連の作業を記憶しておいて、必要な時に再利用できるようにする機能で、atn という拡張子のファイルで提供されます。
これまではそのatnファイルを作成し、photoshopに読み込むことにより登録されているツールを使えるようにしていました。
ツールを提供していくうえでの課題
上記のツール提供形態だと1つ課題がありました。それはファイルパスの固定です。
Photoshopのアクションにスクリプトを登録する際は絶対パスになってしまうためドライブ名含めて全作業者で同じファイルパスで全スクリプトにアクセスできるような状態にする必要がありました。
現状の運用
ツールの管理
REALITYにテクニカルアートチームが立ち上がったことにより、これまでほかのプロダクトとまとめて管理していたものをREALITYに関するものはREALITYで管理をするようにツールの移管を行いました。Photoshopのツールも移管されたものの1つです。
# 現状のフォルダ構成
tools/
└ adobe/
└ jsx/
│ └ 実際に実行される.jsx
└ launcher/
└ launcher.jsx
ツールの管理の改善
REALITYに持ってくることでツールとして関連するものがREALITYのものだけになり管理がしやすくなりました。
また、REALITYに関するものだけの管理になったため機能の追加含めてREALITYで独立して行えるようになりました。例えば機能を追加する際はREALITYの裁量で追加をすることができ、コードの影響範囲もREALITY内の閉じた環境として利用できるものを作ることに専念ができるためツールの制作スピードを上げることができました。
ツール提供形態の改善
管理のREALITYへの移管に伴って、これまでの課題にも対策を施しました。
その方法がランチャーの導入です。
ランチャーの役割としては以下の役割を担っています。
ドライブ名固定の回避
既存のスクリプトのスムーズな利用
ランチャーを導入することでツールのスクリプトはランチャーのjsxからの相対パスで動くようになるため配置の柔軟性が増しました。それによりツールの配置場所としての制約がなくなり、またランチャーからはこれまで使っていたスクリプトを同じように使用できるため使用感としても変わらないものを提供できるように改善を行いました。
ツールの提供形態
ランチャーの導入によりこれまで使用していたatnファイルの提供をやめました。代わりに初回のセットアップ時にのみ各々の環境でランチャー用のjsxをPhotoshopのアクションに登録してもらうことでツールを使えるようにしました。
技術的な仕組み : ランチャーの実装
ここでランチャーの実装につても軽く触れておこうと思います。
ランチャーはExtendScriptによって作成されています。
Windowにlistboxとして親のグループに追加することでUIとして使用可能なツールの一覧を配置しています。そこからアクションとしてスクリプトを選択し実行できます。
以下制作したツールのコードの抜粋です。
#target photoshop
// ベースとなるウィンドウを作成する
var launcher_window = new Window("window", "Launcher Window", [0, 0, 500, 300], creation_properties);
launcher_window.text = "Launcher";
launcher_window.preferredSize.width = 400;
launcher_window.preferredSize.height = 400;
launcher_window.orientation = "column";
launcher_window.alignChildren = ["center","top"];
launcher_window.spacing = 10;
launcher_window.margins = 16;
// 省略...
// ランチャーに並べるコンテンツの定義
var scrollList = [
{
"title": "Action A",
"invoke": function() {
// 指定された時の実行処理
}
},
{
"title": "Action B",
"invoke": function() {
// 指定された時の実行処理
}
},
{
"title": "Action C",
"invoke": function() {
// 指定された時の実行処理
}
},
];
// リストとしてウィンドウに表示する
var launch_list_array = [];
for(var scrollListIndex = 0; scrollListIndex < this.scrollList.length; scrollListIndex++) {
launch_list_array.push(this.scrollList[scrollListIndex].title);
}
var launch_list = content_group.add("listbox", undefined, undefined, {name: "launch_list", items: launch_list_array, multiselect: false});
launch_list.selection = [0];
launch_list.alignment = ["fill","top"];
// リストボックスのダブルクリックイベントを設定
launch_list.onDoubleClick = function()
{
var executeIndex = launch_list.selection.index;
try {
self.scrollList[executeIndex].invoke();
} catch(e) {
alert(e);
}
}
// typeがwindowの場合描画するにはループで出し続ける必要があるのでループさせておく
while (isDone === false) {
app.refresh();
}
注意点としてはWindowタイプで作成した際は、app.refresh();を呼び続けないと表示されないので注意が必要です。
このようにリストで定義しておくことで今後ツールの機能を足す際にはscrollListにのみ手を加えればランチャーとして機能提供できるように作成しました。
現状の課題と今後の展望
現状ランチャー含めてREALITYで提供しているPhotoshopツールのスクリプトはExtendScriptで制作されています。その課題として記述できる構文が古く、例えばletが使えないためスコープに気を付ける等注意する点がいくつかあります。理由として、ExtendScriptの元となったJavaScriptのバージョンはES3となっており、2000年ごろのものがもとになっているためです。
現在Adobeで推奨しているツール制作環境はUXPです。UXPとはAdobeがPluginの開発システムとして提供しているもので、JavaScriptを用いて開発することができます。UXPに乗り換えることで、開発として使えるJavaScriptのサポート範囲がES6まで広がり、UXPとして提供しているAPIによってPhotoshop画面に配置できる等親和性も高まります。
ExtendScriptをUXPで利用できるように載せ替えようとするとAPIとしてまだないもの等もあるため確認事項はいくつかありますが、より使用感の向上を目標に検討していく予定です。
まとめ
今回はPhotoshopのツールの改善内容をご紹介しました。
ツールを整理することで、衣装制作などの効率が向上し、これからもユーザーの皆さんに魅力的なコンテンツをお届けできるように努めていきます!