Photoshop JSX で特定のレイヤーをまとめたものをアイコン化するために実装したものまとめ


概要

PSDファイルから特定のレイヤーを指定し、まとめたものをアイコン化するということをスクリプトで自動化する必要があったので、そこで実装したものについて簡易的なコードと注意点等まとめてみました。

環境

Windows 8.1(64bit)
Photoshop CC 2015(体験版)
Adobe Extendscript Toolkit CC 4.0.0.1(コード作成、デバッグ)

レイヤー名検索

var searchStr = new RegExp("arm.*left");
var flag = layerName.match(searchStr);
if (flag)
{
    // layerNameは"arm~left"を含む
    // ex. layerName = arm_hand_left .etc
}

String.match()を使用することで、文字列検索に正規表現を使用することができるので便利。

レイヤー統合

activeDocument.mergeVisibleLayers ();

対象ドキュメント内の表示されているレイヤーを統合できます。
統合元になるレイヤーは現在アクティブなレイヤーが対象になる点と、表示状態のレイヤーが複数ない場合に実行するとエラーになる点に注意です。

複製

var desc = new ActionDescriptor();
var reg0 = new ActionReference();
reg0.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc.putReference(charIDToTypeID('null'), reg0);

var reg1 = new ActionReference();
reg1.putName(charIDToTypeID('Dcmn'), "複製先のドキュメント名");
desc.putReference(charIDToTypeID('T   '), reg1);

executeAction(charIDToTypeID('Dplc'), desc, DialogModes.NO);

レイヤー画像の加工をするために別ドキュメントにレイヤーを複製しました。
指定レイヤーを別ドキュメントに複製するための関数が見当たらなかったので、動作をScriptingListener機能で記録して利用。

切り出し

var cutObj = activeDocument.activeLayer.bounds;
var x1 = cutObj[0];
var y1 = cutObj[1];
var x2 = cutObj[2];
var y2 = cutObj[3]; 

docObj.crop([x1, y1, x2, y2]);

layer.boudsでレイヤーのピクセルがある範囲を取得し、crop()で指定範囲を切り出します。

正方形に調整

var sizeX = x2-x1;
var sizeY = y2-y1;
var imageMaxSize = sizeX > sizeY ? sizeX : sizeY;
var scalingNum = (iconSize-margin)/imageMaxSize;
var resizeX = sizeX*scalingNum;
var resizeY = sizeY*scalingNum;

activeDocument.resizeImage(resizeX, resizeY);
activeDocument.resizeCanvas(size, size, AnchorPosition.TOPLEFT);

比率が崩れないようにスケーリングします。marginに数値を入れればで余白幅の調整もできます。
resizeImage()で画像、resizeCanvas()でキャンバスのリサイズを行うことができます。

保存

fileObj = new File(file_path);
pngOpt = new PNGSaveOptions();
pngOpt.interlaced = false;
activeDocument.saveAs(fileObj, pngOpt, true, Extension.LOWERCASE);

PNGで保存します。

おまけ

より便利になるように追加した機能を紹介

フォルダ選択

folderName = Folder.selectDialog ("フォルダを作成する場所を選択して下さい。");
if (folderName != null)
{
  // OK押した場合
}

folderNameには選択したフォルダ名が入ります。
キャンセルや閉じるボタンを押した場合、folderNameにはnullが入るので選択した場合のみ進ませたい場合はif文で分岐した方がいいです。

プログレスバー

p_uDlg = new Window('palette','進行度',[100,100,505,180]);
p_uDlg.pBar = p_uDlg.add("progressbar",[10,30,10+384,30+15], 0, 100);
p_uDlg.pBar.value = 0;
p_uDlg.show(); 

プログレスバーを表示できます。valueの数値でバーの値を設定できます。
普段利用するダイアログとほぼ同じですが、Windowのタイプをdialogタイプで利用するとそのウィンドウを閉じないかぎり先に進まないので、ここではpaletteタイプを使用し、表示中でも流れが止まらないようにしています。

フォルダ作成

var folderName = srcDoc.name.split (".")[0];
var folderPath = filePath + folderName + "/";
folderObj = new Folder(folderPath);
var flag = folderObj.exists;
if (!flag) 
{
   // 存在しなければ作成
   folderObj.create();
}

パスを指定してフォルダを作成します。folderObj.existsですでに同階層に同名フォルダがないか確認できます。
フォルダ名にドキュメント名を利用していますが、そのままドキュメント名で取得すると拡張子までついてきてしまうのでsplit()で排除しています。