この記事はKLab Creative Advent Calendar 2018 の 10日目の記事になります。

こんにちは、KLabGames 3Dデザイナー兼R&Dグループのnaoieです。

私はテクスチャなどを製作するうえで利用するPhotoshopの保存に関するアプローチを

新卒の頃から、割と最近までスクリプトで対応していたので、そのお話をさせて頂きます。

概要

表題の通り、ワンボタンで所定の画像ファイルを保存するアプローチをまとめてみました。

アクションを作る

学生の時にはあまり利用していませんでしたが、仕事で扱うテクスチャ画像が多いため

少しでも楽をしたいと思い、アクションによる保存の履歴を作成から着手しました。

保存の工程を録画

アクション1.png

アクションを作り、実行

しかし、保存された画像名に”のコピー”がついてしまう…

のコピーの原因.png

一部の拡張子は保存時、複数のレイヤーが存在すると

画像データの上書き保存を防ぐため、”のコピー”がつくようになります。

※保存オプションの”複製を保存”のチェックを消すことができず、マスクされる。

回避するには…

のコピーの対策.png

保存する画像のレイヤーすべてを統合すると

保存オプションのチェックボックスが解除でき

この状態でアクションを録画すると”のコピー”が付きません

記録したアクションを実行すると…

アクション完了.png

これでpsdと同名の画像データをアクションの自動操作で保存することができました。

しかし、アクションの場合、保存先が絶対パスで記録されてしまうので

アクションの共有が難しいと判断しました。

絶対パス.png

そこで次のアクションに移りました">そこで次のアクションに移りました。

スクリプトを作る

職場の先輩からJavaScriptを薦められたのがきっかけに

勉強するようになりました。

”Adobe Photoshop CC自動化作戦”という、JavaScriptのリファレンスサイトを教えてもらい

どのように利用できるのか調べてみました

機能ごとにリファレンスがまとめられ

▼記載例)

説明とコードが簡潔にまとめられています

▼記載例)

このコードをアクションのように並べれば自動処理ができるのではと思い

スクリプトに着手しました。

Photoshopでスクリプトを作るには?

Adobe Extend Script Toolkitというエディタがあり

そこでスクリプトの作成、実行を行います。

ExtendScript.png

起動すると下図のような画面が表示され

スクリプトを入力後、左上のプルダウンメニューで実行するアプリケーションを選択

再生ボタンを押すと、入力されたスクリプトが実行されます。

スクリプトを作る ~コピペしてみる~

1.処理の流れを考える

 下図のような処理を行えば、保存することが可能になるかと思います。

 基本はアクションを製作する流れとほぼ同じです。

 これらの流れを参考にソースコードを先ほど紹介した”Adobe Photoshop CC

 自動化作戦”を参考に作成してみます。

  ▼処理の流れ 

コピペしたスクリプトと流れは以下のようになります。

//現在のドキュメントの上書き保存
activeDocument.save()
//現在のドキュメントの保存階層取得
var fPath = (app.activeDocument.path);
//PNGファイル作成 ~PNGを保存する設定を宣言~
pngOpt = new PNGSaveOptions();
//↓以下内容=============================
//1.インターレースを有効にするのか true:する false:しない
pngOpt.interlaced = false;
//2.圧縮設定。0~9の数値? デフォルトは0 9になるほど圧縮される
pngOpt.compression = 0;
//3.上記の設定で現在のドキュメントを保存する
activeDocument.saveAs(fPath, pngOpt, true, Extension.LOWERCASE);
// ※fPathにpngOptの設定で同名で保存。拡張子は小文字で。
// ※trueの部分をfalseにすると、別名保存になる。
//  ⇒実行すると保存ポップアップが表れます。

保存結果

 作成したスクリプトで保存した画像がPSDファイルのある同一フォルダだと

 ”のコピー”が付きます…

 保存名を変えれば防げますが、ほかの方法で回避してみようと思います。

方法はざっと考えて以下の2つがあります。

1. WEB用に保存

2. 保存フォルダを分ける

WEBように保存形式で保存するスクリプト

WEB用に保存すると画像が圧縮されるため

同一データとみなされず”のコピー”が付加されなくなります。

先ほどの保存スクリプトにWEB用に保存する処理を追加してみます。

//現在のドキュメントの上書き保存
activeDocument.save()
//現在のドキュメントの保存階層取得
var fPath = (app.activeDocument.path);
//PNGファイル作成 ~PNGを保存する設定を宣言~
pngOpt = new PNGSaveOptions();
//==================================
// 「Web用に保存」のためのオプション Web保存
var options = new ExportOptionsSaveForWeb();
// PNGで保存
options.format = SaveDocumentType.PNG;
//==================================
// 最適化有効
options.optimized = false;
// インターレース無効
options.interlaced = false;
// 保存の実行
activeDocument.exportDocument(fPath, ExportType.SAVEFORWEB, options);

WEB用に保存の処理を通せばデータ名を変えることなく保存が可能です。

でも、この方法だと画像データが圧縮されてしまいます。

圧縮したくない!という方はPSDファイルとは別フォルダに保存するようにしましょう

保存フォルダに分けて保存するスクリプト

pngフォルダを作成し、そのフォルダ内にpngデータが保存されるようにします。

混同してしまうと、データが散らかってしまう為とても便利です。

保存するスクリプトにフォルダを作成するスクリプトを追加する

//現在のドキュメントの上書き保存
activeDocument.save()
//現在のドキュメントの保存階層取得
var fPath = (app.activeDocument.path +"");
//ドキュメントの名前を求める
var dName = activeDocument.name;
//==================================
//PNG保存フォルダ生成
foldername = (fPath + "/png");
folderObj = new Folder(foldername);
folderObj.create();
//==================================
//PNGファイル作成
fileObj = new File( foldername + "/" +dName);
pngOpt = new PNGSaveOptions();
pngOpt.interlaced = false;
activeDocument.saveAs(fileObj, pngOpt, true, Extension.LOWERCASE);

psdファイルと画像データを分別できるのでこちらをお勧めしています。

レイヤー毎にファイルを分けて保存するスクリプト

グループレイヤ毎に画像データを保存したいときに利用します。

保存するのも面倒だし、要素ごとにPSDが増えるのも嫌なので

一つのPSDから複数の画像を保存してくれるスクリプトです。

同一PSDで編集するため、作業効率も上がります。

//現在のドキュメントの上書き保存
activeDocument.save()
//レイヤー名を宣言
var color,spe;
//アクティブなドキュメントを調べる
var docRef = activeDocument;
//アクティブなドキュメントの名前を調べる
var dName = activeDocument.name;
//アクティブなドキュメントがどの階層にあるか調べる
var fPath = activeDocument.path;
//アクティブなドキュメントの階層に率PNGを追加
sPath = fPath + "/png";
//sPathで設定した階層にpngという名前でフォルダを作る
folderObj = new Folder(sPath);
folderObj.create();

//拡張子を覗いた名前の取得
var a = docRef.name.lastIndexOf(".");
var fNameStr = docRef.name.slice(0,a);

//レイヤーセットを1つずつ調べる
//colorespeがあったらフラグ立てて、レイヤーセットを非表示にする
n = docRef.layerSets.length;
for (i=0;i<=n-1;i++){
layerSetName = docRef.layerSets[i].name;
if(layerSetName=="color") {
color=docRef.layerSets[i];
color.visible = false;
}
if(layerSetName=="spe"){
spe=docRef.layerSets[i];
spe.visible = false;
}
}
//pngの保存設定 インターレースしない
pngOpt = new PNGSaveOptions();
pngOpt.interlaced = false;
//括弧に入ったレイヤーセット名があったら、以下の保存設定で保存する
if(color){
color.visible = true;
fileObj = new File(sPath + "/" + fNameStr + "_color.png");
docRef.saveAs(fileObj, pngOpt, true, Extension.LOWERCASE);
pngOpt.alphaChannels = false;
}
if(spe) {
spe.visible = true;
fileObj = new File(sPath + "/" +fNameStr +"_spe.png");
docRef.saveAs(fileObj, pngOpt, true,Extension.LOWERCASE);
spe.visible = false;
}

PSDファイル名+レイヤー名で保存されるようになりました。


禍つヴァールハイトでの利用方法

弊社で開発中のモバイルオンラインRPG"禍つヴァールハイト"というタイトルがあります。

ユーザーは広大なフィールドを巡り、光によって覚醒した敵と戦い、世界の終焉を食い止めるという内容です。

このゲームでは前述したように広大なフィールドを作る必要があり、特に自然をモチーフにしたフィールドでは、地形、材質の変化を多用したいという要望がありました。

それを実現するために、1つのオブジェクトに複数のテクスチャをアサインすることが出来る"5レイヤーシェーダ"というシェーダが利用されています。

5枚もテクスチャを利用するということで、このシェーダで利用するテクスチャを一括りで保存することができるスクリプトを作成しました。

ちなみにこちらのシェーダを作成されたのはAdvent Calendar 2日目を担当されたfo-taさんが作製したシェーダです。

頂点カラー(黒/R/G/B/A)の5チャンネルを割り当てると、それに該当するテクスチャが割り当てられるというものになります。

広大なフィールドを表現するゲームならではのシェーダです。

▼頂点カラー表示

▼テクスチャ表示

グループレイヤー名に割り当てる頂点カラーを入力

それらの名前を識別して自動保存を行っています。先ほどの保存スクリプトを拡張するだけで簡単に作成できます。

▼保存結果

まとめ

スクリプトって本から勉強してもなかなかゲーム制作に合わせた解釈で説明されていないことが多くて、取っ掛かりで挫折してしまうことが多いと思います。

作例を見ても「こうじゃないんだよな」とか「自分が欲しい処理と少し違うんだよな」という風に思うこともあります。

私の場合は、前記で紹介させて頂いた”Adobe Photoshop CC自動化作戦”

他の人が作ったスクリプトからどんなことができるのかを探ることで処理でできることの

流れや手法を知ることから始めていきました。

スクリプトは慣用句のようなもので、今は使わないことかもしれませんが、いつかそれを役立ることがあるくらいのスタンスで勉強をつづけたほうが良いのかなと思っています。

このページを見て頂いた方が、スクリプトや自動化処理に興味を持ってもらえ

少しでもクリエイティブな事に日々の時間を費やせるようになれば幸いです。