Last active
March 30, 2021 12:56
-
-
Save h-tawara/e78adb3a35ac9a8a30029922f911ac9e to your computer and use it in GitHub Desktop.
【Photoshop】レイヤーの書き出しツール
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*================================================================================ | |
# 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