[ss_social_share align=”left” shape=”rounded” size=”small” labels=”label” spacing=”1″ hide_on_mobile=”0″ total=”0″ all_networks=”0″]戦国時代で最も苦労や困難に挫けない人というと山中鹿之助。
どうも、クリーク・アンド・リバー社 COYOTE 3DCG STUDIO テクニカルチーム 戦国大好き人間の中林です。
今回はBoothで有料公開をした『ShotSave ver2.0』で最も苦労をしたアルファチャンネルへのコピーについて紹介します。
こちらで頒布しているので良かったら覗いてみてください。
Booth ShotSave ver2.0
これはレイヤー名の末尾に@Alpha(@A)を加えると、出力をした時の画像のアルファチャンネルに登録できる機能です。
こちらは当初はver2.0に入れる予定はなかったけど、事前に弊スタジオ内でアンケートを取ったところ、圧倒的な100%入れて欲しい機能だったので追加しました。
とはいえver2.0用に作った機能ではなく、スタジオ内で数あるShotSaveのプロジェクト専用カスタムでアーティストから要望された機能の1つです。
そもそもアルファチャンネルへのコピーとは?
主にtgaやbmpの32bitの色数で保存するとできるアルファ用のチャンネルです。
アーティストの作業の段階ではこんな感じで白黒レイヤーになってます。
この白黒レイヤーをアルファチャンネルにコピーするだけです。
フォトショップのスクリプトだけで……
先ずはサンプルのソース
(function() {
// おまけ1・変形用に複製
var copiedDoc = activeDocument.duplicate();
// ➀空レイヤーの作成
root = activeDocument.artLayers.add();
// ➁画像を統合
while(1){
activeDocument.layerSets[0].merge();
if(activeDocument.layerSets.length == 0){
break;
}
}
// レイヤーを全て非表示にする。
for (i=0; i < activeDocument.layers.length; i++) {
activeDocument.layers[i].visible = false;
}
// 説明短縮のためgetByNameを使用
var colorLayer = activeDocument.layers.getByName("normal");
var alphaLayer = activeDocument.layers.getByName("normal@A");
// ➂アルファ用レイヤーのコピーと位置の記録
alphaLayer.visible = true;
alphaLayer.copy(true)
alphaLayer.visible = false;
var souRect = alphaLayer.bounds // コピー前の座標取得
// ➃アルファチャンネルの追加とペースト
var alphaChannel = activeDocument.channels.add();
activeDocument.paste(false);
var tarRect = activeDocument.selection.bounds; // 選択範囲の座標取得
activeDocument.selection.deselect(); // 選択の解除
// ➄選択範囲から座標を取得
var diffX = souRect[0] - tarRect[0];
var diffY = souRect[1] - tarRect[1];
root.translate(diffX, diffY)
// 画像の表示
colorLayer.visible = true;
// 画像保存の処理は情報が沢山あるので省きます。
// おまけ2・保存先のフォルダを開く
getFolder = new Folder("保存先のパス");
getFolder.execute();
// おまけ1・複製ファイルを削除
copiedDoc.close(SaveOptions.DONOTSAVECHANGES);
}());
➀空レイヤーの作成
root = activeDocument.artLayers.add();
これは地味に色々な状態から救ってくれます。
実はユーザーはレイヤーのどこを選択してる状態からのツールを実行するか分かりません。
グループレイヤーなのか、画像レイヤーなのか、はたまた、文字レイヤーの書き終わった瞬間にツールを実行をしているのか。
この状態によってスクリプトの開始でエラーを起こす場合があります。
しかし、空レイヤーを作ることでレイヤー選択が変わるため、その後の処理がスムーズになります。
今回は別の用途でも利用しますが、利用しなくても処理の最初には空レイヤーの作成を入れてます。
➁レイヤーの結合と非表示
// ➁画像を統合
while(1){
activeDocument.layerSets[0].merge();
if(activeDocument.layerSets.length == 0){
break;
}
}
// レイヤーを全て非表示にする。
for (i=0; i < activeDocument.layers.length; i++) {
activeDocument.layers[i].visible = false;
}
ここではアルファレイヤーの情報をコピーし易くするためレイヤーのグループ結合をしています。
for文ではなくWhile文を使ったのはmerge()する度にlayerSetsの内容がズレるためです。
➂アルファ用レイヤーのコピーと位置の記録
alphaLayer.visible = true;
alphaLayer.copy(true)
alphaLayer.visible = false;
var souRect = alphaLayer.bounds // コピー前の座標取得
実はアルファチャンネルのコピーにおいて最も苦労した点です。
このように画像が小さいとものをコピーすると中央に移動してしまいます。
そのために、コピーと一緒にboundsで座標も取得しておきます。
コピーをしたら用なしなのでアルファレイヤーはすぐに非表示にします。
➃アルファチャンネルの追加とペースト
ついでに選択範囲の座標を取得
var alphaChannel = activeDocument.channels.add();
activeDocument.paste(false);
var tarRect = activeDocument.selection.bounds; // 選択範囲の座標取得
activeDocument.selection.deselect(); // 選択の解除
アルファチャンネルを追加ですが、これの良いところは追加するとチャンネルがアクティブになります。そのため、繰り返し作業をするときは毎回アルファチャンネルを消して救ってます。
この状況を利用して画像をペーストするけど、画像が小さいと中央に寄ってしまいます。
➂と同じでアルファチャンネルの座標をコマンドで取ってこれない……。チャンネルにはbounsで座標を取得することはできません!!
でも、レイヤーのペーストで範囲を選んでいる状態になってます。
この状態から選択範囲からbounsで座標を取得できます。
座標を取得したら用が無くなるので、選択は解除します。
本当に欲しいのは座標情報です。
➄選択範囲から座標を取得
var diffX = souRect[0] - tarRect[0];
var diffY = souRect[1] - tarRect[1];
root.translate(diffX, diffY)
ここで仕事をするのが➀で作った空レイヤーをアクティブにするところです。
基本的にはチャンネル情報の座標の変更は難しいです。
しかし、レイヤーの移動はtranslateの座標入力で簡単にできます。
もし、RGBの色情報が空でアルファだけしかないレイヤーがあれば移動をしても画像に影響なくアルファ情報だけ移動できます。
なぜかそんな都合の良いレイヤーがいたので、➂座標から➃座標を引いた値を移動します。
これで、無事に中央に寄る前の位置にアルファチャンネルができました。
後は必要なレイヤーを表示して画像を保存するだけです。
画像の保存に関しては情報が沢山あるので、当ブログでは省きます。
おまけ1:画像の複製(と削除)
// おまけ1・変形用に複製
var copiedDoc = activeDocument.duplicate();
// おまけ1・複製ファイルを削除
copiedDoc.close(SaveOptions.DONOTSAVECHANGES);
基本的に僕の作るPhotoshopツールは複製してから処理をしています。
それは複製をしてしまえば、画像をマージしようが表示のオンオフを変えてしまおうが元のデータには一切影響なく安全に作業できるからです。
どんなにデータを汚しても最後に消してしまえば元データに影響はありません。
逆に複製した画像が残るとツールに問題があると分かるので、途中で失敗して処理が止まったかユーザーに伝わりやすいので重宝してます。
仮に止まっても、複製データを手動で消すだけで復帰ができます。
こちらは基本にして奥義くらいな感じで多く活用してます。
おまけ2:保存先のフォルダを開く
getFolder = new Folder("保存先のパス");
getFolder.execute();
作業の動線として画像に限らず多くの作業で、保存するとそのフォルダを開きます。でも、その方法は手動です。
ShotSave ver2.0を始め、最近スタジオのShotSaveシリーズには積極的にフォルダを開く機能を取り入れてます。
実はアルファチャンネルの対応よりもこの機能の実装の方が多くのアーティストに喜ばれています。
Photoshopとの戦いはこれからだ!!
不思議なことにShotSaveのカスタム要望は毎回新しい要望が増えており、一度として同じものはありません。
その中でも今のところ最も苦労したのはアルファチャンネルのコピーです。
ただ、これで安心して次回のShotSaveはレイヤー名を仕様に合わせるくらいで済みそう……
アーティスト「ブログ中にすみません、新しいプロジェクトでShotSaveをお願いしたいんですけど」
僕「大丈夫ですよ。なんなら、最新機能でアルファチャンネルの追加もできますよ」
アーティスト「これ良いですね。こんな感じで
レイヤーAをRチャンネルに
レイヤーBをGチャンネルに
レイヤーCをBチャンネルに
コピーして1枚の画像で出力できませんか」
僕「Photoshopよ。願わくば、我に七難八苦を与えたまえ!!(バッタン)」
アーティスト「TAさんがまた倒れた!!」
『TAの知識がRGBチャンネルのコピーを作れると信じて……』
ShotSaveの進化はこれからも続く!!
Boothの他のツールもよろしく
こんな苦労があったかは謎ですが、弊スタジオからBoothで他にもツールを頒布してます。その多くが無料です。
Booth COYOTE 3DCG Studio
良かったら使ってみてください。