この記事はKLab Creative Advent Calendar 2018 の 10日目の記事になります。
こんにちは、KLabGames 3Dデザイナー兼R&Dグループのnaoieです。
私はテクスチャなどを製作するうえで利用するPhotoshopの保存に関するアプローチを
新卒の頃から、割と最近までスクリプトで対応していたので、そのお話をさせて頂きます。
表題の通り、ワンボタンで所定の画像ファイルを保存するアプローチをまとめてみました。
学生の時にはあまり利用していませんでしたが、仕事で扱うテクスチャ画像が多いため
少しでも楽をしたいと思い、アクションによる保存の履歴を作成から着手しました。
しかし、保存された画像名に”のコピー”がついてしまう…
一部の拡張子は保存時、複数のレイヤーが存在すると
画像データの上書き保存を防ぐため、”のコピー”がつくようになります。
※保存オプションの”複製を保存”のチェックを消すことができず、マスクされる。
保存する画像のレイヤーすべてを統合すると
保存オプションのチェックボックスが解除でき
この状態でアクションを録画すると”のコピー”が付きません
これでpsdと同名の画像データをアクションの自動操作で保存することができました。
しかし、アクションの場合、保存先が絶対パスで記録されてしまうので
アクションの共有が難しいと判断しました。
そこで次のアクションに移りました">そこで次のアクションに移りました。
職場の先輩からJavaScriptを薦められたのがきっかけに
勉強するようになりました。
”Adobe Photoshop CC自動化作戦”という、JavaScriptのリファレンスサイトを教えてもらい
どのように利用できるのか調べてみました
機能ごとにリファレンスがまとめられ
▼記載例)
説明とコードが簡潔にまとめられています
▼記載例)
このコードをアクションのように並べれば自動処理ができるのではと思い
スクリプトに着手しました。
Photoshopでスクリプトを作るには?
Adobe Extend Script Toolkitというエディタがあり
そこでスクリプトの作成、実行を行います。
起動すると下図のような画面が表示され
スクリプトを入力後、左上のプルダウンメニューで実行するアプリケーションを選択
再生ボタンを押すと、入力されたスクリプトが実行されます。
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用に保存する処理を追加してみます。
//現在のドキュメントの上書き保存
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自動化作戦”や
他の人が作ったスクリプトからどんなことができるのかを探ることで処理でできることの
流れや手法を知ることから始めていきました。
スクリプトは慣用句のようなもので、今は使わないことかもしれませんが、いつかそれを役立ることがあるくらいのスタンスで勉強をつづけたほうが良いのかなと思っています。
このページを見て頂いた方が、スクリプトや自動化処理に興味を持ってもらえ
少しでもクリエイティブな事に日々の時間を費やせるようになれば幸いです。
KLabのクリエイターがゲームを制作・運営で培った技術やノウハウを発信します。
合わせて読みたい
KLabのクリエイターがゲームを制作・運営で培った技術やノウハウを発信します。