【CEP教程

您所在的位置:网站首页 ps动作没有反应 【CEP教程

【CEP教程

2023-05-31 17:46| 来源: 网络整理| 查看: 265

上篇文章我们介绍了Action Manager的入门知识,讲如何通过ScriptListener插件来让Ps输出AM代码为我所用。同时介绍了AM的独特的代码结构,都是源于底层C的转换逻辑,使得对大多数开发者而言,异常晦涩难懂。上篇文章相当于是基础知识的介绍,离真正实际应用还差的很多,基本上你只能通过拷贝Ps输出的代码,自己简单改吧改吧凑合着用,如果Ps没有输出,就无能为力了。

这篇文章,以及下一篇,我们开始介绍AM实战部分,深入了解AM的运作机制,通过一些前人的积累和经验,让我们自己也可以顺藤摸瓜的开始自己写AM代码,实现想要的功能。

对于我们日常想要的操作,无非就是希望从宿主获取一些信息(GET操作),设置宿主的一些状态(SET操作),针对这两个操作,我们分为两篇文章分别介绍,中篇介绍如何从Ps中获取信息,下篇介绍如何设置这些信息。这么安排是有考虑的,一方面相比SET而言,GET其实要相对简单一些(虽然SET有ScriptListener辅助,但离开它确实举步维艰),另外一方面SET部分会用到GET讲的数据结构。

让我们马上开始吧~

本文是此系列教程中的精华,内容较长,要保持耐心。文章是我长时间思考、研究成果,内容原创,全网独一份,转载请注明出处。

1. ActionDescriptor数据获取

上一篇文章我们讲过,Ps核心通过动作(Action)和事件(Event)两套机制来响应每个操作,在每个动作、事件的过程中,都会有一个目标对象描述,表示我要对某个对象做动作,这个对象描述就是ActionDescriptor,这个对象描述里头包含了目标对象的一些属性信息,所以我们只要获取到这个目标对象描述,然后从中获取到这个对象的属性信息,就可以了。

我们现在以获取图层属性为例子,进行展开介绍,仔细看不要开小差!

我们先从选中某个图层为入口,当你选中一个图层的时候,会看到ScriptListener输出如下代码

123456789var desc1 = new ActionDescriptor();var ref1 = new ActionReference(); ref1.putName( stringIDToTypeID( "layer" ), "Rectangle" );desc1.putReference( stringIDToTypeID( "null" ), ref1 );desc1.putBoolean( stringIDToTypeID( "makeVisible" ), false );var list1 = new ActionList(); list1.putInteger( 117 );desc1.putList( stringIDToTypeID( "layerID" ), list1 );executeAction( stringIDToTypeID( "select" ), desc1, DialogModes.NO );

我们把这段代码的结构用脑图来表示

可以很清晰的看出来,执行了动作select,这个动作的描述符是ActionDescriptor,这个描述符里头表示的目标对象,通过null(target) 属性表示,这个属性值是一个ActionReference,它里头设置了一个layer属性,它的值是Rectangle,意思就是图层名称是Rectangle的目标对象。

这里面有一个很关键的地方

12var ref1 = new ActionReference(); ref1.putName( stringIDToTypeID( "layer" ), "Rectangle" );

ActionReference是一个动作引用对象,它表示我们对某个目标对象的引用,上面的代码理解为我要引用一个名称是Rectangle的图层,于是ref1这个对象就包含了这个图层的引用,拿到这个引用之后,我们可以把它传给很多地方(比如前面的代码,把它传给了一个选择动作的描述符)。现在我们的目标是想要获取到这个图层的属性,于是我们需要想办法获取到这个图层的动作描述符(ActionDescriptor)。AM提供了一个方法executeActionGet,让我们可以通过引用拿到它的描述符

123declare interface Application { executeActionGet(reference: ActionReference): ActionDescriptor;}

所以我们可以这样,拿到这个图层的描述符

123var ref1 = new ActionReference(); ref1.putName( stringIDToTypeID( "layer" ), "Rectangle" );var layerDescriptor = executeActionGet(ref1);

从输出的结果可以看到layerDescriptor是一个ActionDescriptor对象

拿到这个图层的ActionDescriptor之后,我们如何去获取它的属性和值呢?它又都有哪些属性和值呢?

做过Javascript开发的小伙伴,都应该知道,我们如果拿到一个未知的JS对象,想要知道它里头包含哪些属性或者方法,可以用for去遍历它的属性,比如

123456var obj = new SomeUnknownObject();for (var i in obj) { if (obj.hasOwnProperty(i)) { console.log(i + " => " + obj[i]) }}

同理,我们也可以想办法遍历出来那个ActionDescriptor对象里头都包含了哪些属性和值,但是方法不太一样,如果你查阅官方文档,可以看到ActionDescriptor有一个count的属性,它表示这个AD里头key的数量,于是依然可以通过遍历把这些key弄出来,这里需要注意,要把key拿出来,得通过AD的getKey这个方法,这些方法都在AD的官方文档api里头能找到。

1234567var ref1 = new ActionReference(); ref1.putName( stringIDToTypeID( "layer" ), "Rectangle" );var layerDescriptor = executeActionGet(ref1);for (var i=0; i target,也就是当前选中的图层 ref1.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));var layerDescriptor = executeActionGet(ref1);

上面这行代码也很重要,它给ActionReference设置了一个枚举类型,指的是当前target->layer,也就是当前选中的图层,为什么说它很重要呢?它是AM给我们提供的一个相当于快捷途径,用来表示当前处于被激活状态的一些目标对象,除了选中的图层之外,还有当前选中的文档,选中的通道,选中的工具等等,都可以通过这种方式来获取到,比如上面我们一直都在讲图层,现在我们来把目标对象换成当前文档,比如我想知道当前文档的一些信息,比如名称,id,图层数量等。

来,跟着我的思路:我们创建一个ActionReference,把当前文档作为属性设置进去,然后反向获取到它的ActionDescriptor,就可以遍历出它的属性了

1234567var ref1 = new ActionReference(); // 这几个key: Dcmn, Ordn, Trgt,你就背下来就好了 // 如果看着不习惯,也可以换成string的表达方式document, ordinal, target ref1.putEnumerated(charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));var docDescriptor = executeActionGet(ref1);var json = ADToJson(docDescriptor);$.writeln(json.title);

你可以把整个Document的属性都dump出来,看看一个Document,都具备了哪些属性,本质上,它也是一个属性树,逐层往下挖掘,就能够找到你想要的目标对象了,比如前文我们一直提到过的一个问题:当选中多个图层的时候,activeLayer只返回其中一个,如何能够获取到所有被选中的图层信息呢?

我们可以从文档(document)的属性里面找到一个叫targetLayersIDs的属性,这个属性的值,就是当前被选中的图层的ID列表,那结合前面我们介绍的内容,我们就可以拿到选中图层列表的所有信息了,我们来试一下代码

123456789101112var ref1 = new ActionReference(); ref1.putEnumerated(charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));var docDescriptor = executeActionGet(ref1);// 我们可以通过打印发现targetLayersIDs是一个list类型,通过getList拿到一个数组var list = docDescriptor.getList(stringIDToTypeID("targetLayersIDs"));// 遍历这个list,拿到图层ID,ActionList的数据结构和AD也差不多,数组里头的元素是ActionReference对象for (let i=0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3