ps新增插件 通道工具

This commit is contained in:
tianmo committed 2026-08-20 11:58:15 +08:00
1 parent 0905159c6e
commit 21d0137575
8 files changed
+1130

No files matched your search

@@ -0,0 +1,385 @@
#target photoshop
/*
* 重命名图层 - 独立版
*
* 使用方法:
* Photoshop -> 文件 -> 脚本 -> 浏览,选择本文件。
*
* 支持规则:
* %n 正序编号:1、2、3...
* %%n 倒序编号
* %nn 两位编号:01、02、03...
* %n### 编号 + 原图层名
* %%n### 倒序编号 + 原图层名
* %n=5 从 5 开始编号
* 旧文字=>新文字 替换名称中的第一个匹配文本
*
* CEP 调用:
* 先把 CMM_RENAME_AUTO_RUN 改为 false,加载本文件后调用:
* cmm_batchName("%n###", true, true);
* 第三个参数控制是否重命名图层组,省略时默认为 true。
*/
// 独立运行时设为 true;作为 CEP 函数库加载时改为 false。
var CMM_RENAME_AUTO_RUN = true;
// suspendHistory 使用的全局参数。
var CMM_RENAME_EXPRESSION = "";
var CMM_RENAME_FILTER_SUBLAYERS = true;
var CMM_RENAME_INCLUDE_GROUPS = true;
function cmm_s2t(value) {
return stringIDToTypeID(value);
}
function cmm_c2t(value) {
return charIDToTypeID(value);
}
function cmm_getActiveLayerId() {
var ref = new ActionReference();
ref.putProperty(cmm_s2t("property"), cmm_s2t("layerID"));
ref.putEnumerated(
cmm_s2t("layer"),
cmm_s2t("ordinal"),
cmm_s2t("targetEnum")
);
return executeActionGet(ref).getInteger(cmm_s2t("layerID"));
}
function cmm_getSelectedLayerIds() {
var ids = [];
var ref = new ActionReference();
ref.putProperty(cmm_c2t("Prpr"), cmm_s2t("targetLayers"));
ref.putEnumerated(cmm_c2t("Dcmn"), cmm_c2t("Ordn"), cmm_c2t("Trgt"));
var desc = executeActionGet(ref);
// Photoshop 单选图层时,部分版本不返回 targetLayers。
if (!desc.hasKey(cmm_s2t("targetLayers"))) {
ids.push(cmm_getActiveLayerId());
return ids;
}
var list = desc.getList(cmm_s2t("targetLayers"));
var backgroundOffset = 0;
try {
if (app.activeDocument.backgroundLayer) {
backgroundOffset = -1;
}
} catch (ignoreBackgroundError) {
backgroundOffset = 0;
}
for (var i = 0; i < list.count; i += 1) {
var layerIndex = list.getReference(i).getIndex(cmm_c2t("Lyr ")) + 1;
var layerRef = new ActionReference();
layerRef.putProperty(cmm_c2t("Prpr"), cmm_c2t("LyrI"));
layerRef.putIndex(
cmm_c2t("Lyr "),
layerIndex + backgroundOffset
);
var layerDesc = executeActionGet(layerRef);
ids.push(layerDesc.getInteger(cmm_c2t("LyrI")));
}
return ids;
}
function cmm_selectLayerById(layerId, addToSelection) {
var ref = new ActionReference();
var desc = new ActionDescriptor();
ref.putIdentifier(cmm_c2t("Lyr "), layerId);
desc.putReference(cmm_c2t("null"), ref);
desc.putBoolean(cmm_c2t("MkVs"), false);
if (addToSelection) {
desc.putEnumerated(
cmm_s2t("selectionModifier"),
cmm_s2t("selectionModifierType"),
cmm_s2t("addToSelection")
);
}
executeAction(cmm_c2t("slct"), desc, DialogModes.NO);
}
function cmm_restoreLayerSelection(ids) {
if (!ids || ids.length === 0) {
return;
}
cmm_selectLayerById(ids[0], false);
for (var i = 1; i < ids.length; i += 1) {
cmm_selectLayerById(ids[i], true);
}
}
function cmm_indexOf(arr, value) {
for (var i = 0; i < arr.length; i += 1) {
if (arr[i] === value) {
return i;
}
}
return -1;
}
/*
* 根据选项排除图层组。普通图层和图层组都使用 Photoshop 图层 ID,
* 因此必须选中目标后通过 typename 判断其类型。
*/
function cmm_filterLayerGroups(ids, includeLayerGroups) {
if (includeLayerGroups) {
return ids;
}
var result = [];
for (var i = 0; i < ids.length; i += 1) {
cmm_selectLayerById(ids[i], false);
if (app.activeDocument.activeLayer.typename !== "LayerSet") {
result.push(ids[i]);
}
}
return result;
}
/*
* 如果父图层组和它的子图层同时被选中,只保留父图层组。
*/
function cmm_filterSubLayer(ids) {
var result = [];
for (var i = 0; i < ids.length; i += 1) {
cmm_selectLayerById(ids[i], false);
var parent = app.activeDocument.activeLayer.parent;
var isChildOfSelectedGroup = false;
while (parent && parent.typename !== "Document") {
if (cmm_indexOf(ids, parent.id) !== -1) {
isChildOfSelectedGroup = true;
break;
}
parent = parent.parent;
}
if (!isChildOfSelectedGroup) {
result.push(ids[i]);
}
}
return result;
}
function cmm_isBlank(value) {
return value === undefined ||
value === null ||
String(value).replace(/\s/g, "") === "";
}
/*
* 核心函数。函数名和原插件保持一致,方便 CEP 直接调用。
*/
function cmm_batchName(expression, filterSubLayers, includeLayerGroups) {
if (app.documents.length === 0) {
throw new Error("请先打开一个 Photoshop 文档");
}
if (cmm_isBlank(expression)) {
throw new Error("重命名规则不能为空");
}
var rule = String(expression);
var ids = cmm_getSelectedLayerIds();
// 为兼容原来的两个参数调用,第三个参数省略时默认包含图层组。
if (includeLayerGroups === undefined) {
includeLayerGroups = true;
} else {
includeLayerGroups = Boolean(includeLayerGroups);
}
// 先排除图层组。这样关闭“重命名图层组”时,选中的普通子图层
// 不会因为其父图层组也被选中而被过滤掉。
ids = cmm_filterLayerGroups(ids, includeLayerGroups);
if (filterSubLayers && includeLayerGroups) {
ids = cmm_filterSubLayer(ids);
}
if (ids.length === 0) {
throw new Error("当前选择中没有符合选项的可重命名图层");
}
var reverse = rule.indexOf("%%") !== -1;
if (reverse) {
rule = rule.replace("%%", "%");
}
// %n=5、%nn=5、%%n=5 均支持;默认从 1 开始。
var startNumber = 1;
var startMatch = rule.match(/n=(-?\d+)/);
if (startMatch) {
startNumber = parseInt(startMatch[1], 10);
if (isNaN(startNumber)) {
startNumber = 1;
}
rule = rule.replace("=" + startMatch[1], "");
}
try {
for (var i = 0; i < ids.length; i += 1) {
cmm_selectLayerById(ids[i], false);
var activeLayer = app.activeDocument.activeLayer;
var oldName = activeLayer.name;
var number;
if (reverse) {
number = startNumber + ids.length - 1 - i;
} else {
number = startNumber + i;
}
var newName = rule.replace("###", oldName);
if (rule.indexOf("%nn") !== -1) {
var paddedNumber = number;
if (number >= 0 && number < 10) {
paddedNumber = "0" + number;
}
newName = newName.replace("%nn", paddedNumber);
} else if (rule.indexOf("%n") !== -1) {
newName = newName.replace("%n", number);
} else if (rule.indexOf("=>") !== -1) {
var separatorIndex = rule.indexOf("=>");
var searchText = rule.substring(0, separatorIndex);
var replacementText = rule.substring(separatorIndex + 2);
if (searchText === "") {
throw new Error("替换的原文字不能为空");
}
// 与原插件一致:每个图层只替换第一个匹配项。
newName = oldName.replace(searchText, replacementText);
}
activeLayer.name = newName;
}
} finally {
cmm_restoreLayerSelection(ids);
}
return ids.length;
}
function cmm_historyRenameRunner() {
cmm_batchName(
CMM_RENAME_EXPRESSION,
CMM_RENAME_FILTER_SUBLAYERS,
CMM_RENAME_INCLUDE_GROUPS
);
}
/*
* 把整次批量重命名合并成一条 Photoshop 历史记录。
*/
function cmm_runBatchName(expression, filterSubLayers, includeLayerGroups) {
CMM_RENAME_EXPRESSION = String(expression);
CMM_RENAME_FILTER_SUBLAYERS = Boolean(filterSubLayers);
CMM_RENAME_INCLUDE_GROUPS = includeLayerGroups === undefined ?
true : Boolean(includeLayerGroups);
app.activeDocument.suspendHistory(
"重命名图层",
"cmm_historyRenameRunner()"
);
}
function cmm_showRenameDialog() {
if (app.documents.length === 0) {
alert("请先打开一个 Photoshop 文档");
return;
}
var dialog = new Window("dialog", "重命名图层");
dialog.orientation = "column";
dialog.alignChildren = "fill";
var ruleGroup = dialog.add("group");
ruleGroup.add("statictext", undefined, "规则:");
var ruleInput = ruleGroup.add("edittext", undefined, "###%%n");
ruleInput.characters = 28;
var groupCheckbox = dialog.add(
"checkbox",
undefined,
"重命名图层组"
);
groupCheckbox.value = true;
var filterCheckbox = dialog.add(
"checkbox",
undefined,
"过滤已选父图层组中的子图层"
);
filterCheckbox.value = false;
groupCheckbox.onClick = function () {
// 不重命名图层组时,所有已选普通图层都会参与重命名,
// “过滤子图层”选项不再适用。
filterCheckbox.enabled = groupCheckbox.value;
};
var helpText = dialog.add(
"statictext",
undefined,
"%n 正序 %%n 倒序 %nn 两位编号\n%n=5 从5开始编号 ### 原名称\n旧文字=>新文字 可执行替换",
{ multiline: true }
);
helpText.alignment = "left";
var buttonGroup = dialog.add("group");
buttonGroup.alignment = "right";
buttonGroup.add("button", undefined, "取消", { name: "cancel" });
buttonGroup.add("button", undefined, "确定", { name: "ok" });
ruleInput.active = true;
if (dialog.show() !== 1) {
return;
}
try {
cmm_runBatchName(
ruleInput.text,
filterCheckbox.value,
groupCheckbox.value
);
} catch (error) {
alert("重命名失败:" + error.message);
}
}
if (CMM_RENAME_AUTO_RUN) {
cmm_showRenameDialog();
}