Photoshop UXP 保存元と同じディレクトリーにドキュメントを保存する

UXP

Photoshop 24.2よりgetEntryWithUrlメソッドが追加されました。このメソッドを使えばもうstring型のパスからEntry型のパスを生成できるので本記事のような回りくどいやり方でローカルファイルにアクセスする必要がなくなりました。
詳しくこちらを参照

そろそろ今年も終わりに近づいております。正直今の仕事に色々思う節のある最近で、一応DTP関係の仕事をやってはいますがTwitterを見渡すと周りに比べてあんまりDTPにも精通していないと感じる今日この頃です。
ところでPhotoshop UXPにはsaveAsメソッドがあります。これはExtendScriptにおけるsaveAsと同じように指定の拡張子で保存オプションと共にPhotoshopで開いているドキュメントを保存できるメソッドなのですがUXPでは現状保存先についてはダイアログを開いてentry型のファイルを渡す必要があります。Photoshop24.0からfsモジュールも解禁されてローカルファイルへのアクセスがダイアログ抜きにできるようになったのですがfsモジュール以外のメソッド、まさにPhotoshopにおけるsaveAsのようなメソッドに関しては現状string型のファイルパスを渡して保存する方法が見当たりません。しかし例えばpsdファイルを開いてそのまま開いたpsdファイルと同じディレクトリーにjpgファイルを保存したいという方は多いと思います。今回ExtendScriptにおけるsaveAsのように同じディレクトリーに保存する方法をUXPで実現してみます。

ここで触れているfsモジュールはあくまでUXPの専用モジュールfsであってNode.jsとは全く別物なので注意。(詳しくはUXP開発者にとって存在する三つのfsを参照)

事前に必要な知識

今回実際の保存メソッド構築に入る前にPhotoshop24.0から追加されたファイルモジュールfsに知らない方はAdobe UXP v6.3 fileSystem触ってみた。を参照。またはUXPにおけるローカルファイルへの基本のアクセスをご存知でない方はUXPにおけるローカルファイルへのアクセスの記事を参照してください。

問題の整理

前述の通りUXPの基本はエンドユーザーからダイアログの許可がない限り直接ローカルへのアクセスがUXPのシステムからできないことです。fsモジュールを使えばファイルの書き込み、移動、コピーといった事がダイアログを通さずにできますがここにはPhotoshop関係のメソッドはありません。これでは直接保存場所をPhotoshopのモジュールからアクセスできないのでsaveAsメソッドを使う際に必ずダイアログが必要というわけです。
しかしfsモジュールは前述の通りファイル移動メソッドがあります。つまりPhotoshopでとりあえずどこでもいいからどこかのディレクトリーにファイルを保存してやれば良いのです。保存した後にfsのrenameメソッドで元々のドキュメントが保存されていたディレクトリーに移動すれば目的が達成できます。しかしUXPにおいてダイアログを通す必要のないディレクトリーとは?それがPluginのtempフォルダーになります。このtempフォルダーですが一時的にPluginの保存場所として作成されるフォルダーでここにファイルを長期間保存はできませんが一時的に保管しておくことは可能です。(該当のPluginが閉じられると自動的に消滅するため注意)はい、もうどうすれば良いのかお分かりですね。

実際にコードを構築

手順としては以下のようになります

  • 保存先のディレクトリー(元々保存されていたファイルのディレクトリー)をstring型のパスを事前に取得
  • ドキュメントをsaveAsメソッドでtempフォルダーに保存。
  • 保存されたtempフォルダーのディレクトリーをstring型のパスを取得。
  • tempフォルダーに保存されたドキュメントをそのまま保存したいディレクトリーにfs.renameメソッドで移動

まずtempフォルダーですが以下のメソッドで簡単に取得できます。

これをそのままsaveAsメソッドの引数に渡せばtempフォルダー内にドキュメントが保存されます。
このentry型のオブジェクトですがnativePathプロパティとしてstring型のファイルパスを持っています。なのでこれを使えばそのままfs.renameメソッドで使えますね。ただしファイルプロトコルとしてfile:が必要なので注意。保存前のファイルパスやファイル名はapp.activeDocument内のプロパティにあります。(tempフォルダーに保存する前に取得した方が良さそう)
ただ実際に保存先を指定するのにファイルパスから親ディレクトリーのパスを抜き出したりする必要があります。デフォルトでUXPはNode.jsのようなpathモジュールを持っていません。これを使用するためにpath-browserifyを使用します。webpackなんかと一緒に使ってモジュールから使用できるようにします。
最終的なコードは以下のようになります。

これでダイアログを通さずに元々保存されていたディレクトリーにそのまま別の拡張子のファイルとして保存することができました。
勿論応用すればそのまま親フォルダーに保存、もしくはデスクトップに保存といったこともできます。ただし注意したいのは保存された直後に
開いてる元々のPhotoshop上のドキュメントはそのままだと保存先をtempフォルダーだと認識しているのでそのまま作業して保存してPluginを閉じるとtempフォルダーと共に消滅します。なので上記メソッドを実行直後に必ずドキュメントを閉じるようにするなりした方が良いでしょう。またfs.renameメソッドは移動先に同名のファイルがあるとそのままファイルを上書きする仕様みたいなので要注意です。

tempフォルダー
そのままアクティブなドキュメントを保存するとtempフォルダーに保存される。

結局Photoshopモジュールにもっと便利なメソッドは追加されないのか?

正直かなり回りくどいやり方ですよね。ローカルへのフルアクセス自体実装されて間もないので現状具体的にstring型のパスを扱える
保存メソッドなどがPhotoshopモジュールに実装されるような情報自体ありませんがそのうち実装されるような気もしないでもありません。ただ具体的な情報が無い以上いつになるのか、もしくは実装されるのか不明です。というわけで取り急ぎこういった保存メソッドの実装する必要がある場合はできなくもないという記事でした。

参考

Beer 寄付してサイトを応援する。