本文写于2018年。中文世界关于PhotoShop插件开发的内容比较少,该文记录了对一些基础概念的理解,可能对初学者有些帮助
本文涉及的ps是ps cc 2017 && 2018
Photoshop
- 智能对象的内容不仅仅可以是图片,也可以是psd、svg等文件类型
Photoshop scripting
-
ExtendScript和JavaScript区别
ExtendScript是Adobe开发的脚本语言,基于JavaScript,针对Adobe的产品特性,增强了脚本语言的功能。后缀名是
jsx。ps:Windows系统中如果双击
.js的文件,系统会使用微软的js解析引擎来执行脚本。而改为jsx则不会,而是优先使用Photoshop的脚本即系引擎来执行。 -
ps怎样执行脚本
- 将脚本文件放到
ps.app/Presets(mac)中,重启ps,在file->scripts中执行 file->browse-> 选择脚本执行
- 将脚本文件放到
-
photoshop object model
也称为DOM(Photoshop Document Object model),是通过脚本文件操作ps中文件的
API。其中包含了许多类和方法。比如
app、document、preferences -
ExtendScript SDK中也包含了UI的组件和网络组件
但网络组件是socket的请求,没有上层封装。估计用起来不爽。
-
ExtendScript中一些小技巧
layers["Layer1"] && layers.getByName("Layer1"),通过图层名称获取图层- layer.bounds是取值以
左上角为原点,bounds属性是layer的四个顶点的值组成的数组----[minX, minY, maxX, maxY],所以访问width时需bounds[2] - bounds[0] - 图层合并后的图层的尺寸是所有图层的最小包围矩形,此处所说的尺寸不一定是bounds
- 上面说的最小包围矩形,有一种情况例外,就是有剪贴蒙版的情况
- layer的bounds属性,是图层有像素值的点组成的四个点即不包含透明部分。如果要看包含透明的大小,需要command+T,通过参考点才能看到
- 直接用ps 打开image时,可能是索引模式,要记得先convertRGB,否则后续操作可能不work
- 转智能对象方式来替换图层内容时,一般会新建一个图层,然后转为智能对象。后续操作中,新建图层时的变量就不能再用了,要重新获取一遍图层。
- saveas要比export快
- app.open(new File(""));,如果出错会抛出异常
- 执行shell命令时,文件路径中不能包含空格,空格要是用
\空格代替 - 学习了剪贴蒙版和图片蒙版
- 怎么从画布整体上,进行缩放?
- resizeImage(但速度比较慢)
- 创建一个图层,将图层涂色并弄成透明(opacity=0),然后选中要进行缩放的图层和这个空白图层(script不方便选中多个图层,可以将这两个图层放到一个图层组中,将图层组转为智能对象),创建为智能对象。缩放这个智能对象就可以了(这个速度快)
- 由于对document进行裁剪的操作比较耗时,可以用新建文档的方式进行替换
- 图层复制到另一个文档中后,图层的bounds不会变
- document.artLayers[0]是ps树状图层图中最上面的图层
-
ExtendScript的坑
- document.saveas方法保存的图片比较大,document.export使用saveforweb导出的图片比较小
- saveas的操作可以使用command+option+z进行撤销,但export却不可以
- 通过evalScript进行html端和jsx端交互时,返回和传入的只有一种数据类型,就是字符串,包括jsx返回其他数据类型时。
- UnitValue使用说明
- var w = UnitValue(1, "px");--1像素/var w = UnitValue(1, "in");
- UnitValue.value
- bounds的类型实际上是UnitValue的数组形式
- exportDocument时,导出文件名中如果包含空格,导出后会被替换为横线
- extendscript中用ps打开有透明通道的图片时,该会生成一个非锁定的图层,且是rgb模式;如果打开一个无透明通道的图片时,则是索引模式,且生成的图层是锁定的,此时如果要移动该图层等操作,需要先解锁。
- 使用app.system执行shell命令时,如果要执行多行命令,需要将多条拼接成一条。比如想cd到某个目录,再操作。不能执行两边app.system。
- 必须先选中要合并的图层组,再merge,否则之前被选中的图层的visible会自动改为true
- 当两个智能对象图层关联着同一个对象时,修改这个对象,不仅两个图层的显示的内容会自动改变,两个图层的图层名也会修改
- 通过export导出的图片dpi固定是72,不会跟随psd中设置的分辨率走,当使用存储功能保存图片时,dpi才会被更改。
-
关于ps和extendscript中的bounds
我们先把所有跟bounds相关的东西列一下,[artlayer|layerset].[bounds|boundsNoEffects],在右侧面板位置的属性中也有bounds,
command+T后左上角位置的参考点bounds-
必须选中图层树中的对象后,右侧面板中属性才有值。但不是所有对象,都有属性。图层组(layerset)就没有。普通图层有,画板也有
-
由于artlayer和layerset都是layer的子类,所以都有bounds属性
-
普通图层
- 对于非智能对象,三者相同,都是有像素值的最小包围矩形
- 对于智能对象且像素值的最小包围矩形周围还有透明区域的话,
command+T是包含透明区域的矩形,而前两者则还是最小包围矩形
-
图层组(layerset)
- layerset.bounds和
command+T都是像素值的最小包围矩形 - 没有面板中的属性值
- layerset.bounds和
-
画板(artboard)
由于目前extendscript并没有artboard的api,所以会将artboard认为是layerset,但与上面的layerset区别很大。画板背后有个大区域,通过“图像大小”能看出来,我们假设这个大区域左上角原点是origin0
- artboard
- artboard没有
command+T - artboard右侧面板属性有值,画板尺寸和距离origin0的坐标
- artboard.bounds相当于layerset.bounds,有像素值的最小包围矩形,注意,是距离origin0
- artboard没有
- 对于artboard中的图层
- 非智能对象
- 右侧面板属性值和
command+T,是像素最小包围矩形距离画板左上角原点的坐标 - layer.bounds是,像素最小包围矩形距离origin0的坐标
- 右侧面板属性值和
- 智能对象
command+T是包含像素值以外透明区域的矩形,距离画板原点的坐标- 右侧面板属性,有像素值最小包围矩形,距离画板原点坐标
- layer.bounds,是有像素值区域最小包围矩形,距离origin0的位置,可不是距离当前画板左上角原点
- 非智能对象
- 通过am获取的bounds
- artboard的bounds是画板尺寸和距离origin0的坐标,等价于右侧面板属性
- layer的bounds等价于layer通过api获取的bounds即layer.bounds
- artboard
-
-
ActionReference & ActionDescriptor & ActionList
- ActionList类似一种数组数据结构
- executeAction(typeID, desp, dialog) 和 executeActionGet(ref)都能返回结果,返回desp。但接收参数不同。desp是ActionDescriptor类型,ref是ActionReference类型
- ActionDescriptor.putReference(ref);ref是ActionReference类型
- ActionReference.putProperty(stringIDToTypeID('property') , stringIDToTypeID("targetLayers"));有过滤作用,该方法使得返回结果中只包含targetLayers这个属性
-
图层的itemIndex和action manager(简称am)中的index
-
am的ref.getIndex,获取
- 有背景图层,getIndex从0开始
- 无背景图层,getIndex从0开始
-
对于layer.itemIndex
- 有背景图层,itemIndex从1开始
- 无背景图层,itemIndex从1开始
-
am的ref.putIndex(typeid, index),用于获取layer
am的ref.putIndex逻辑中,背景图层永远占据着0位置,不管背景图层存不存在
- 有背景图层时,putIndex(typeid, 0),表示获取背景图层
- 无背景图层时,putIndex(typeid, 1),表示获取第一个图层,而putIndex(typeid, 0)是错误的
-
am中获取numberOfLayers,是不包括背景图层的图层数量
-
如果有背景图层,而且其他图层都只能盖在背景图层之上。背景图层解锁后,就成为普通图层了
-
发现一个奇怪现象,如果都是artlayer,则layer.itemIndex从1开始递增。但如果新建一个layerset(图层组),则itemIndex会跳过去。比如原来有四个artlayer,itemIndex是1、2、3,现在将2位置的artlayer删除,新建一个layerset,则新的itemIndex是1、3、4
-
-
关于sample
-
adobe photoshop/preset/scripts/目录下有一些ps已经支持的脚本
-
extend script tool kit目录下也有些例子
CC Extension
CC Extension是更先进的一组为Adobe工具扩展功能的开发平台
- 该平台只针对CC版本的Adobe工具。
- 支持HTML、JS、Nodejs开发
- 底层执行Adobe工具的工作仍然是调用上面章节所说的scripting api
相比使用ExtendScript进行scripting开发,CC Extension在网络操作、UI方面更强大。
- 感觉Nodejs是用于服务端开发的,CC Extension感觉主要是开发前段页面,所以哪些地方可以使用Nodejs?