ps插件:烘焙图层样式

This commit is contained in:
tianmo
2026-08-20 18:43:02 +08:00
parent 21d0137575
commit c78fa2500d
@@ -0,0 +1,216 @@
#target photoshop
/*
Photoshop Bake Layer Style 1.5 (PS 2026 兼容版)
功能:
1. 校验:当前是否选中了图层;
2. 校验:当前图层是否包含可转换的图层样式;
3. 显示确认窗口;
4. 确认后复制当前图层作为工作副本;
5. 隐藏原图层,将其保留为备份;
6. 在工作副本上执行"图层 > 图层样式 > 创建图层"
7. 若命令失败,自动回滚到脚本执行前的状态。
*/
(function () {
var DIALOG_TITLE = "创建图层样式";
var DIALOG_MESSAGE = "是否烘焙图层样式到单独图层?";
if (app.documents.length === 0) {
alert("请先打开文档并选择一个带有图层样式的图层。", DIALOG_TITLE, true);
return;
}
// ========== 校验 1:当前是否选中了图层 ==========
function hasSelectedLayer() {
try {
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayers"));
ref.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID("targetLayers"))) {
var list = desc.getList(stringIDToTypeID("targetLayers"));
return list.count > 0;
}
return false;
} catch (e) {
return false;
}
}
// ========== 校验 2:当前图层是否包含图层样式 ==========
function hasLayerStyle() {
try {
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerEffects"));
ref.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var desc = executeActionGet(ref);
if (!desc.hasKey(stringIDToTypeID("layerEffects"))) {
return false;
}
// layerEffects 键存在不代表有样式,需检查内部是否有实际效果
var fxDesc = desc.getObjectValue(stringIDToTypeID("layerEffects"));
var effectKeys = [
"dropShadow",
"innerShadow",
"outerGlow",
"innerGlow",
"bevelEmboss",
"chromeFX",
"solidFill",
"gradientFill",
"patternFill",
"frameFX",
"frameFXStyle"
];
for (var i = 0; i < effectKeys.length; i++) {
if (fxDesc.hasKey(stringIDToTypeID(effectKeys[i]))) {
return true;
}
}
return false;
} catch (e) {
return false;
}
}
// ========== 执行前置校验(缺一不可) ==========
if (!hasSelectedLayer()) {
alert("当前未选中任何图层,请先选择一个图层后再执行。", DIALOG_TITLE, true);
return;
}
if (!hasLayerStyle()) {
alert("当前图层没有图层样式,无法烘焙。\n请先为图层添加样式(如投影、描边、外发光等)。", DIALOG_TITLE, true);
return;
}
// ========== 确认对话框 ==========
var dialog = new Window("dialog", DIALOG_TITLE);
dialog.orientation = "column";
dialog.alignChildren = ["fill", "center"];
dialog.spacing = 16;
dialog.margins = 20;
var message = dialog.add("statictext", undefined, DIALOG_MESSAGE);
message.alignment = "center";
var buttonGroup = dialog.add("group");
buttonGroup.orientation = "row";
buttonGroup.alignment = "right";
buttonGroup.spacing = 10;
buttonGroup.add("button", undefined, "取消", { name: "cancel" });
var confirmButton = buttonGroup.add(
"button",
undefined,
"确认",
{ name: "ok" }
);
dialog.defaultElement = confirmButton;
dialog.center();
if (dialog.show() !== 1) {
return;
}
// ========== 核心执行逻辑(已验证可运行) ==========
var documentReference = app.activeDocument;
var originalLayer = documentReference.activeLayer;
var originalName = originalLayer.name;
var initialHistoryState = documentReference.activeHistoryState;
try {
var workingLayer = originalLayer.duplicate();
originalLayer.visible = false;
workingLayer.name = originalName + "_烘焙";
workingLayer.visible = true;
selectLayerExclusively(documentReference, workingLayer);
createLayersFromLayerStyle();
} catch (error) {
try {
documentReference.activeHistoryState = initialHistoryState;
} catch (rollbackError) {
try {
originalLayer.visible = true;
documentReference.activeLayer = originalLayer;
} catch (restoreError) {
// 保留最初的 Photoshop 错误信息。
}
}
var details = error.message;
if (error.number !== undefined) {
details += "\n错误编号:" + error.number;
}
if (error.line !== undefined) {
details += "\n脚本行号:" + error.line;
}
alert(
"创建图层样式失败。\n\n" +
details +
"\n\n请确认当前图层包含可转换的图层样式。",
DIALOG_TITLE,
true
);
}
function selectLayerExclusively(documentReference, layerReference) {
try {
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putIdentifier(
stringIDToTypeID("layer"),
layerReference.id
);
descriptor.putReference(
stringIDToTypeID("null"),
reference
);
descriptor.putBoolean(
stringIDToTypeID("makeVisible"),
false
);
executeAction(
stringIDToTypeID("select"),
descriptor,
DialogModes.NO
);
} catch (selectError) {
documentReference.activeLayer = layerReference;
}
}
function createLayersFromLayerStyle() {
// 使用 ScriptingListener 录制的标准代码:
// 用 Mk (Make) 命令,将当前图层的 Lefx (Layer Effects) 属性创建为新图层。
var idMk = charIDToTypeID("Mk ");
var desc = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref1 = new ActionReference();
var idLyr = charIDToTypeID("Lyr ");
ref1.putClass(idLyr);
desc.putReference(idnull, ref1);
var idUsng = charIDToTypeID("Usng");
var ref2 = new ActionReference();
var idPrpr = charIDToTypeID("Prpr");
var idLefx = charIDToTypeID("Lefx");
ref2.putProperty(idPrpr, idLefx);
var idLyr2 = charIDToTypeID("Lyr ");
var idOrdn = charIDToTypeID("Ordn");
var idTrgt = charIDToTypeID("Trgt");
ref2.putEnumerated(idLyr2, idOrdn, idTrgt);
desc.putReference(idUsng, ref2);
executeAction(idMk, desc, DialogModes.NO);
}
})();