PhotoShop脚本之Action Descriptor

最近研究PS工具,发现部分API不能直接获取到的图层信息,如描边色值、渐变色值等是可以通过PhotoShop的内置对象——Action Descriptor获取的。

1、PhotoShop脚本简介

PhotoShop脚本主要是基于JavaScript语言,以及PhotoShop的语言ExtendScript。这里不做赘述。
想要学习ExtendScript的小伙伴可以看看此官方文档:
https://wwwimages2.adobe.com/content/dam/acom/en/devnet/photoshop/pdfs/photoshop-cc-javascript-ref-2015.pdf

2、语言

PhotoShop支持几种脚本语言,Mac平台有AppleScript,Windows平台有VBScript,以及两个平台都支持的JavaScript。在这里我用的就是JavaScript语言,文件后缀是.jsx。

3、工具

PhotoShop脚本可以用任何文本编辑来写,这里推荐使用Adobe的IDE,叫Adobe ExtendScript Tookit,其支持断点调试,还可以通过Data Browser窗口查看对象的属性和方法。

4、语法

PhotoShop获取信息的一种方式是使用ExtendScript在文本对象模型DOM(Document Object Model)中访问和修改PSD源文件中对象的属性,直观而方便,但不能实现所有的PS操作。
PhotoShop获取信息的另一种方式是通过使用动作代理(ActionManager)的方式,可以实现比DOM更多的操作,但貌似不支持AppleScript。

动作代理主要类有ActionDescriptor,ActionReference,ActionList。

ActionDescriptor相当于一个存储属性和值的字典,
ActionList是一个存储相同属性的值的数组,
ActionReference存储一个action的引用

5、使用Action Descriptor

使用ActionManager看起来比使用ExtendScript要复杂许多,但好在Adobe有个监听Action的插件,下载地址:
Windows:http://download.adobe.com/pub/adobe/photoshop/win/13.x/Win_Scripting_Plug-In.zip
Mac:https://link.csdn.net/?target=http%3A%2F%2Fdownload.adobe.com%2Fpub%2Fadobe%2Fphotoshop%2Fmac%2F13.x%2FScripting_Plug_In_Release.dmg

下载解压后将ScriptListener.8li拷贝到Adobe Photoshop/Plug-ins/目录下即可。

重开PS,操作将会被记录在桌面的ScriptingListenerJS.log和ScriptingListenerVB.log中

切记不用时把该插件移除,需要时再复制到Plug-ins目录下,以免撑爆磁盘以及影响PS操作性能。

6、示例

这里举一个例子,获取文本图层的Outline色值
首先,下载安装好Adobe监听Action的插件,然后打开PS,新建一个空白文档,并新建一个文本层,输入文本:测试,选中文本图层
测试图

然后打开桌面的ScriptingListenerJS.log文本文档,把里面的内容删除并保存。
在PS中双击文本图层为其添加描边效果,然后打开ScriptingListenerJS.log
然后看到其操作代码:

通过查阅官方文档可以得知其对应的事件名,文档链接:https://wwwimages2.adobe.com/content/dam/acom/en/devnet/photoshop/pdfs/photoshop_scriptref_js.pdf

然后通过使用ExtendScript中的方法app. charIDToTypeID(charID)以及app.typeIDToStringID(id),可以得到对应Action的名字分别为(顺序由上到下)color,red,grain,blue,frameFX和layerEffects

然后获取选中图层的ActionDescriptor,使用前记得把文本图层设置为选中状态:

function getActiveLayerDescriptor()
{
	var ref = new ActionReference();
	ref.putEnumerated(char2Type("Lyr "), char2Type("Ordn"), char2Type("Trgt"));
	return executeActionGet(ref);
}

然后判断是否存在刚才所说的节点,其中顺序需要反过来,由下到上
先在当前图层的ActionDescriptor查找名为layerEffects的子节点,若存在则判断在layerEffects的ActionDescriptor中是否存在frameFX节点,以此类推,直到找到color节点下的三个Double类型的变量,用ActionDescriptor.getDouble方法,分别获取red,grain,blue的值

7、完整代码:

function getID(str)
{
    return app.stringIDToTypeID( str );
}

function getActiveLayerDescriptor()
{
	var ref = new ActionReference();
	ref.putEnumerated(char2Type("Lyr "), char2Type("Ordn"), char2Type("Trgt"));
	return executeActionGet(ref);
}

function descToColorList( colorDesc )
{
    return rgbTxt = [roundColor(colorDesc.getDouble(1382293536)),
					roundColor(colorDesc.getDouble(1198681632)),
					roundColor(colorDesc.getDouble(1114382368))];
}

function changeToHex(rgbTxt)
{
	var value = "";
	for(var i = 0, len = rgbTxt.length; i < len; i++)
	{
		var string = rgbTxt[i].toString(16);
		if(string.length < 2)
		{
			string = "0" + string;
		}
		value += string;
	}
	return value;
}

function roundColor(x) 
{
    x = Math.round(x);
    return (x > 255) ? 255 : x;
}

var currentDesc = getActiveLayerDescriptor();

var layerEffectsID = getID( "layerEffects" );
if(currentDesc.hasKey(layerEffectsID))
{
	var layerEffectsDesc = currentDesc.getObjectValue(layerEffectsID);
	var frameFXID = getID("frameFX");
	if(layerEffectsDesc.hasKey(frameFXID)){
		var frameFXDesc = layerEffectsDesc.getObjectValue(frameFXID);
		var colorID = getID("color");
		if(frameFXDesc.hasKey(colorID) && frameFXDesc.getBoolean(getID("enabled")))
		{
			var colorDesc = frameFXDesc.getObjectValue(colorID);
			var rgbTxt = descToColorList(colorDesc);
			var rgbHexTxt = changeToHex(rgbTxt);
			alert(rgbHexTxt);
		}
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值