动作代理 (Action Manager)

Photoshop 的 DOM(Document Object Model)封装了大部分常用操作,但有些底层功能没有对应的 DOM 方法。这时就需要使用 Action Manager——一个直通 Photoshop 内部命令系统的接口。

executeAction / executeActionGet 在 Photoshop 2025 (26.x) 中可能受限。本章演示的 typeID 转换、ActionDescriptor 操作、ActionReference 构造和 putCustomOptions 均工作正常。如果使用 executeAction 遇到错误,建议优先使用 DOM API 实现相同功能。

调用录制的动作 (app.doAction)

app.doAction() 是 DOM API 提供的方法,用于调用 Photoshop 动作面板中已录制的动作(Action),而非通过 Action Manager 发送底层命令。

javascript
app.doAction("动作名称", "动作组名称");

动作名称和组名称与 Photoshop 动作面板中显示的名称一致:

javascript
// 调用"Methods"动作组中的"调整尺寸"动作
app.doAction("调整尺寸", "Methods");

// 指定对话框模式
app.doAction("添加水印", "品牌动作", DialogModes.NO);

DialogModes 参数与执行模式一致:NO(静默)、YES(显示对话框)、ERROR(仅错误)。

与 Action Manager 的区别

方面app.doAction()executeAction()
类别DOM API 方法Action Manager 函数
动作来源动作面板中已录制的动作代码构造的 ActionDescriptor
编程复杂度无需编码动作本身需要构造描述符和引用
灵活性固定流程,参数化有限完全可编程
版本兼容性所有版本PS 2025 中可能受限

适用场景

  1. 录制代替编码 — 复杂的图像处理流程(添加品牌水印、特定滤镜组合),先在动作面板中录制,再用 doAction() 调用,比手动编写 Action Manager 代码更稳定
  2. 混合使用 — DOM API 做参数化操作(调整尺寸、添加图层),doAction() 处理固定流程
  3. 串联工作流 — 将多个动作通过脚本按序调用,形成完整的自动化流水线

Action Manager 介绍

Photoshop 内部使用 Action Manager 处理所有操作。DOM API 方法(如 layer.move())只是对 Action Manager 命令的封装。Action Manager 让你直接发送这些底层命令。

核心函数:

  • executeAction(event, descriptor, dialogModes) — 执行操作(PS 2025 中可能不可用)
  • executeActionGet(reference) — 获取对象信息(PS 2025 中可能不可用)

所有操作通过 ActionDescriptor(描述符)和 ActionReference(引用)来构造。

类型 ID 转换

Action Manager 使用 4 字符代码(charID)或字符串(stringID)标识操作、属性和类。需要先转换为数字 ID:

javascript
var eventID = charIDToTypeID("Opn ");  // 4 字符代码,不足补空格
var propID = stringIDToTypeID("target");

// 常用转换
var idSet = charIDToTypeID("set ");
var idGet = charIDToTypeID("get ");
var idDocument = charIDToTypeID("Dcmn");
var idLayer = charIDToTypeID("Lyr ");

ActionDescriptor

ActionDescriptor 是键值对容器,用于构建操作参数:

javascript
// 创建描述符
var desc = new ActionDescriptor();

// 添加各种类型的数据
desc.putInteger(charIDToTypeID("Nmbr"), 42);
desc.putString(charIDToTypeID("Nm  "), "图层名称");
desc.putBoolean(charIDToTypeID("Hdn "), false);
desc.putUnitDouble(charIDToTypeID("Dmtr"), 1414165953, 72); // 像素单位
desc.putEnumerated(charIDToTypeID("Md  "),
                   charIDToTypeID("Clr "),
                   charIDToTypeID("RGB "));

// 嵌套描述符
var innerDesc = new ActionDescriptor();
innerDesc.putInteger(charIDToTypeID("Val "), 100);
desc.putObject(charIDToTypeID("T   "), charIDToTypeID("Obj "), innerDesc);

// 添加引用
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
desc.putReference(charIDToTypeID("T   "), ref);

// 读取值
var val = desc.getInteger(charIDToTypeID("Nmbr"));
alert("值: " + val);

desc.erase(charIDToTypeID("Nmbr"));
alert("剩余键数: " + desc.count);

putUnitDouble 的单位常量

单位常量值说明
像素1414165953 ("#Pxl")像素值
百分比1428557424 ("#Prc")百分比
毫米1397695024 ("#Mlm")毫米
1416511600 ("#Pnt")

ActionReference

ActionReference 用于引用 Photoshop 中的对象:

javascript
// 创建引用
var ref = new ActionReference();

// 引用当前文档
ref.putEnumerated(charIDToTypeID("Dcmn"),
                  charIDToTypeID("Ordn"),
                  charIDToTypeID("Trgt"));

// 引用文档的第 1 个图层
ref.putIndex(charIDToTypeID("Lyr "), 0);

// 引用特定 ID 的文档
ref.putIdentifier(charIDToTypeID("Dcmn"), 42);

// 引用指定名称的图层
ref.putName(charIDToTypeID("Lyr "), "背景");

// 引用属性
ref.putProperty(charIDToTypeID("Prpr"), charIDToTypeID("Nm  "));
ref.putEnumerated(charIDToTypeID("Dcmn"),
                  charIDToTypeID("Ordn"),
                  charIDToTypeID("Trgt"));

示例 1:存储与读取脚本配置

putCustomOptions / getCustomOptions 是 Action Manager 级别的持久化存储,在 PS 2025 中工作正常:

javascript
var storeDesc = new ActionDescriptor();
storeDesc.putString(charIDToTypeID("Msge"), "你好,下次见!");
storeDesc.putInteger(charIDToTypeID("Num "), 42);
storeDesc.putBoolean(charIDToTypeID("Hdn "), false);

// 保存到 Photoshop 配置(跨会话持久化)
putCustomOptions(charIDToTypeID("MyS"), storeDesc, true);

// 重新读取
var loadedDesc = getCustomOptions(charIDToTypeID("MyS"));
if (loadedDesc) {
  var msg = loadedDesc.getString(charIDToTypeID("Msge"));
  var num = loadedDesc.getInteger(charIDToTypeID("Num "));
  alert(msg + " 数字是 " + num);
}

executeAction / executeActionGet(版本兼容说明)

在 Photoshop 2024 及更早版本中,executeActionexecuteActionGet 是 Action Manager 的核心执行函数:

javascript
// executeActionGet — 获取文档信息(此写法在 ≤PS 2024 可用)
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Prpr"), charIDToTypeID("inf "));
ref.putEnumerated(charIDToTypeID("Dcmn"),
                  charIDToTypeID("Ordn"),
                  charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
var width = desc.getUnitDoubleValue(charIDToTypeID("Wdth"));
javascript
// executeAction — 旋转画布(此写法在 ≤PS 2024 可用)
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Dcmn"),
                  charIDToTypeID("Ordn"),
                  charIDToTypeID("Trgt"));
desc.putReference(charIDToTypeID("T   "), ref);
desc.putUnitDouble(charIDToTypeID("Ang "), charIDToTypeID("#Ang"), 90);
executeAction(charIDToTypeID("Rtt "), desc, DialogModes.NO);

DialogModes 可选:YES(显示对话框)、NO(静默执行)、ERROR(仅显示错误)。

实际工作中,优先使用 DOM API 代替 Action Manager:

  • doc.width / doc.height 替代 executeActionGet
  • doc.rotateCanvas() 替代 executeAction(Rtt...)

使用建议

  1. 优先使用 DOM API — DOM API 更简洁、可读性更好。只有 DOM 不支持的场景才用 Action Manager。
  2. 熟悉 charID — 常用 charID 如 "Dcmn"(文档)、"Lyr "(图层)、"Trgt"(当前目标)等需要熟记。
  3. 使用 ScriptingListener 插件 — Adobe 提供 ScriptingListener 插件,录制操作时会在日志文件中输出对应的 Action Manager 代码,是学习 charID 和描述符结构的利器。
  4. DialogModes.NO — 大多数脚本操作应使用 NO 模式静默执行,避免弹出对话框打断自动化流程。