Skip to content

Instantly share code, notes, and snippets.

@h-tawara
Last active March 30, 2021 12:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h-tawara/e78adb3a35ac9a8a30029922f911ac9e to your computer and use it in GitHub Desktop.
Save h-tawara/e78adb3a35ac9a8a30029922f911ac9e to your computer and use it in GitHub Desktop.
【Photoshop】レイヤーの書き出しツール
/*================================================================================
# LayerExporter for Photoshop
# レイヤーをpng,jpg,psdで書き出すスクリプト
================================================================================*/
#target photoshop
//================================================================================
const SCRIPT_TITLE = "LayerExporter";
const EDIT_TEXT_WIDTH_MINSIZE = 100;
const EDIT_TEXT_HEIGHT_MINSIZE = 30;
//================================================================================
var mFolderPath;
//================================================================================
// 実行部
app.activeDocument.suspendHistory(SCRIPT_TITLE,"Run()");
//================================================================================
// メイン処理
function Run() {
// 単位設定を保持+Pixelに変換
var myRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
SettingWindow();
// 初期設定
grpSelectType.selectType.selection = 0;
grpSaveType.selectType.selection = 0;
// 書き出し先の初期値に現在のパスを指定
// 保存されていない場合にはパスがないのでtry,catchで
try {
if (activeDocument.path != null) {
mFolderPath = activeDocument.path;
grpFilePath.filePath.text = mFolderPath;
}
} catch(e) {
// 特に何もしない
}
// 参照ボタンが押された時
grpFilePath.btnReference.onClick = function () {
FolderReference ();
// 再描画
refresh();
}
// 実行ボタンが押されたら
grpSystemButton.btnApply.onClick = function () {
if (SettingCheck ()) {
LayerExport();
}
}
dlg.show();
// 単位設定を元に戻す
preferences.rulerUnits = myRulerUnits;
}
//================================================================================
// ウィンドウの設定
function SettingWindow () {
// --ウィンドウの生成
dlg = new Window ("dialog", SCRIPT_TITLE);
dlg.minimumSize = [200, 100];
dlg.margins = [10, 10, 10, 10];
// --Panel > Setting
dlg.pnlSetting = dlg.add("panel", undefined,"Setting");
dlg.pnlSetting.alignment = "left";
// --Setting
grpFilePath = dlg.pnlSetting.add("group");
grpFilePath.alignment = "left";
grpFilePath.title = grpFilePath.add("statictext", undefined, "書き出し先:");
grpFilePath.filePath = grpFilePath.add("edittext",undefined, mFolderPath);
grpFilePath.filePath.minimumSize = [EDIT_TEXT_WIDTH_MINSIZE, undefined];
grpFilePath.filePath.maximumSize = [EDIT_TEXT_WIDTH_MINSIZE, EDIT_TEXT_WIDTH_MINSIZE];
grpFilePath.btnReference = grpFilePath.add("button",undefined, "参照", { name:"reference"});
grpSaveType = dlg.pnlSetting.add("group");
grpSaveType.alignment = "left";
grpSaveType.sText = grpSaveType.add("statictext", undefined, "保存形式:");
grpSaveType.selectType = grpSaveType.add("dropdownlist", undefined, ["PNG", "JPG", "PSD"]);
grpSelectType = dlg.pnlSetting.add("group");
grpSelectType.alignment = "left";
grpSelectType.sText = grpSelectType.add("statictext", undefined, "対象レイヤーを選択:");
grpSelectType.selectType = grpSelectType.add("dropdownlist", undefined, ["Select Layers", "All Layers"]);
grpTrim = dlg.pnlSetting.add("group");
grpTrim.cBoxTrim = grpTrim.add("checkbox", undefined, "トリミングを行う");
grpTrim.cBoxTrim.minimumSize = [200, undefined];
grpTrim.alignment = "left";
grpSerialNum = dlg.pnlSetting.add("group");
grpSerialNum.cBoxSerialNum = grpSerialNum.add("checkbox", undefined, "連番追加");
grpSerialNum.cBoxSerialNum.minimumSize = [200, undefined];
grpSerialNum.alignment = "left";
// --システムボタン
grpSystemButton = dlg.add("group");
grpSystemButton.btnApply = grpSystemButton.add("button",undefined, "実行", { name:"apply"});
grpSystemButton.btnApply.minimumSize = [EDIT_TEXT_WIDTH_MINSIZE, EDIT_TEXT_HEIGHT_MINSIZE];
grpSystemButton.btnCancel = grpSystemButton.add("button",undefined, "閉じる", { name:"cancel"});
grpSystemButton.btnCancel.minimumSize = [EDIT_TEXT_WIDTH_MINSIZE, EDIT_TEXT_HEIGHT_MINSIZE];
}
//================================================================================
// レイヤーのエクスポート処理
function LayerExport() {
try {
var targetLayers = [];
var selection = grpSelectType.selectType.selection.text;
if (selection == "All Layers") {
targetLayers = activeDocument.layers;
} else {
targetLayers = GetSelectedLayers(targetLayers);
}
switch(grpSaveType.selectType.selection.text) {
case "PNG":
case "JPG":
LayerExportImage(targetLayers);
break;
case "PSD":
LayerExportPSD(targetLayers);
break;
}
alert("書き出しが完了しました。", "完了通知");
} catch(e) {
alert (e);
}
}
//================================================================================
// 単一画像のエクスポート処理
function LayerExportImage(targetLayers, ext) {
var copyVisibles = [];
var ext = "." + grpSaveType.selectType.selection.text.toLowerCase();
// 選択レイヤーの表示状態を保存
for (var i = 0; i < targetLayers.length; i++) {
copyVisibles.push(targetLayers[i].visible);
}
DisableLayers(targetLayers);
for (var i = 0; i < targetLayers.length; i++) {
var path = mFolderPath + "/" ;
// 連番の追加
path += AddSerialNum();
path += targetLayers[i].name;
// 名前に「.png」があると保存時に「.png.png」などになるので削除
path = path.replace(ext, "");
//レイヤーの表示状態を制御
if (i >= 1) {
targetLayers[i-1].visible = false;
}
targetLayers[i].visible = true;
switch(grpSaveType.selectType.selection.text) {
case "PNG":
SavePNG(path);
break;
case "JPG":
SaveJPG(path);
break;
}
// トリミングするか?
if (grpTrim.cBoxTrim.value) {
// ファイルオープンの際は、拡張子まで名前が必要
Trimming (path + ext);
}
}
// 表示状態を元に戻す
for (var i = 0; i < targetLayers.length; i++) {
targetLayers[i].visible = copyVisibles[i];
}
}
//================================================================================
// PSDのエクスポート処理
function LayerExportPSD(targetLayers) {
var ext = "." + grpSaveType.selectType.selection.text.toLowerCase();
var oriDocName = activeDocument.name;
var names = GetLayerNames(targetLayers);
for (var i = 0; i < names.length; i++) {
var path = mFolderPath + "/" ;
SetActiveDocument(oriDocName);
var copyDoc = activeDocument.duplicate()
activeDocument = copyDoc
path += AddSerialNum();
path += names[i];
path = path.replace(ext, "");
RemoveLayers(names, names[i]);
SavePSD(path);
copyDoc.close(SaveOptions.DONOTSAVECHANGES);
}
}
//================================================================================
// 指定ドキュメントをアクティブに
function SetActiveDocument(name) {
for (var i = 0; i < documents.length; i++) {
if (documents[i].name == name) {
activeDocument = documents[i];
return;
}
}
}
//================================================================================
// レイヤーリストから名前リストを取得
function GetLayerNames(layers) {
var names = new Array();
for (var i = 0; i < layers.length; i++) {
names.push(layers[i].name);
}
return names;
}
//================================================================================
// 指定レイヤー以外を削除
function RemoveLayers(names, ignoreName) {
ClearSelectLayers();
var doc = app.activeDocument;
var allLayers = [];
var allLayers = CollectAllLayers(doc, allLayers);
for (var i = 0; i < allLayers.length; i++) {
if (allLayers[i].name == ignoreName) {
continue;
}
for (var j = 0; j < names.length; j++) {
if (allLayers[i].name == names[j]) {
AddSelectionLayer(allLayers[i].name);
}
}
}
RemoveSelectLayers();
}
//================================================================================
// 全てのレイヤーの選択を解除
function ClearSelectLayers() {
var idselectNoLayers = stringIDToTypeID( "selectNoLayers" );
var desc21 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref7 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref7.putEnumerated( idLyr, idOrdn, idTrgt );
desc21.putReference( idnull, ref7 );
executeAction( idselectNoLayers, desc21, DialogModes.NO );
}
//================================================================================
// 全てのレイヤーを取得
function CollectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
allLayers.push(theLayer);
CollectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
//================================================================================
// 指定レイヤーの追加選択
function AddSelectionLayer(layerName) {
var actDesc= new ActionDescriptor();
var actRef= new ActionReference();
actRef.putName( charIDToTypeID('Lyr '), layerName);
actDesc.putReference( charIDToTypeID('null'), actRef );
actDesc.putEnumerated( stringIDToTypeID('selectionModifier'),
stringIDToTypeID('selectionModifierType'),
stringIDToTypeID('addToSelection') );
actDesc.putBoolean( charIDToTypeID('MkVs'), false );
executeAction( charIDToTypeID('slct'), actDesc, DialogModes.NO );
}
//================================================================================
// 選択レイヤーを全て削除
function RemoveSelectLayers() {
var idDlt = charIDToTypeID( "Dlt " );
var desc14 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref2 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref2.putEnumerated( idLyr, idOrdn, idTrgt );
desc14.putReference( idnull, ref2 );
var idLyrI = charIDToTypeID( "LyrI" );
var list2 = new ActionList();
list2.putInteger( 27 );
desc14.putList( idLyrI, list2 );
executeAction( idDlt, desc14, DialogModes.NO );
}
//================================================================================
// 連番の追加処理
function AddSerialNum() {
var addText = "";
// 連番追加するか?(同一名回避用)
if (grpSerialNum.cBoxSerialNum.value) {
// 0埋め3桁
var num = ("00" + i).slice(-3) + "_";
addText += num;
}
return addText;
}
//================================================================================
// 対象レイヤーのリストを全て非表示に
function DisableLayers(targetLayers) {
for (var i = 0; i < targetLayers.length; i++) {
targetLayers[i].visible = false;
}
}
//================================================================================
// PNG形式で保存
function SavePNG(path) {
var saveFileObj = new File(path);
var opt = new PNGSaveOptions(); //PNGの設定
opt.interlaced = false; //インターレースなし
activeDocument.saveAs(saveFileObj, opt, true, Extension.LOWERCASE)
}
//================================================================================
// JPG形式で保存
function SaveJPG(path) {
var saveFileObj = new File(path);
var opt = new JPEGSaveOptions(); //JPGの設定
opt.quality = 12;
activeDocument.saveAs(saveFileObj, opt, true, Extension.LOWERCASE)
}
//================================================================================
// PSD形式で保存
function SavePSD(path) {
var saveFileObj = new File(path);
var opt = new PhotoshopSaveOptions();
opt.alphaChannels = true;
opt.annotations = true;
opt.embedColorProfile = false;
opt.layers = true;
opt.spotColors = false;
activeDocument.saveAs(saveFileObj, opt, true, Extension.LOWERCASE);
}
//================================================================================
// フォルダの選択処理
function FolderReference() {
try {
mFolderPath = Folder.selectDialog("★フォルダを指定してください");
grpFilePath.filePath.text = mFolderPath;
} catch (e) {
alert(e);
}
}
//================================================================================
// 設定のエラーチェック処理
function SettingCheck() {
if (mFolderPath == null) {
alert("フォルダが選択されていません", "エラー通知");
return false;
}
return true;
}
//================================================================================
// トリミング処理
function Trimming(path) {
var path02 = path;
// 最初に「/」や「\」があるとファイルオープンの際にコケるので回避
if (path02[0] == '/' || path02[0] == '\\') {
path02.substr(1);
}
var fileObj = new File(path);
app.open(fileObj);
// アルファでトリミング
activeDocument.trim(TrimType.TRANSPARENT, true, true, true, true);
SavePNG (path);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
//================================================================================
// 選択レイヤーを取得
function GetSelectedLayers(){
var selectList = [];
var idGrp = stringIDToTypeID( "groupLayersEvent" );
var descGrp = new ActionDescriptor();
var refGrp = new ActionReference();
refGrp.putEnumerated(charIDToTypeID( "Lyr " ),charIDToTypeID( "Ordn" ),charIDToTypeID( "Trgt" ));
descGrp.putReference(charIDToTypeID( "null" ), refGrp );
executeAction( idGrp, descGrp, DialogModes.ALL );
var myActiveLayer = app.activeDocument.activeLayer;
for (var i = 0; i < myActiveLayer.layers.length; i++) {
selectList.push(myActiveLayer.layers[i])
}
Undo();
return selectList;
}
//================================================================================
// Undo処理
function Undo() {
executeAction(charIDToTypeID("undo"), undefined, DialogModes.NO);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment