⽤JS和PSDom来掌控Photoshop-绘制篇
要做的:
由两篇⽂章组成:
基础绘制篇--以PhotoShop的Document为舞台,在上⾯绘制⽂字和任意形状
图层操作篇--PS最强⼤的是图层操作,通过操作图层,我们可以完成各种想做的事情,最经典的就是⽤于UI⾃动切图.
有了这些PSDom概念后,你会发现其实开发PS插件蛮简单的,PSDom⾮常强⼤。
不做的:
1) 不涉及Channel操作,对位图像素操作我们不关⼼
2) 不涉及PhotoShop界⾯编程。因为PS界⾯编程随着版本变化,有好多种⽅式,⼀直在改变。
C++⽅式,强⼤,但是难度较⼤,不是三⾔两语说得清楚的
As3 Flex⽅式,简单易⽤,和PSDom交互⽅便,但是适合Adobe CS系列
Html5⽅式,简单应⽤,和PSDom交互⽅便,但是适合Adobe CC系列
但不管如何,核⼼的PhotoShop操作是通过PSDom API公开出来的,
这个不管版本如何变,其本⾝DOM是不会发⽣较⼤变化的。
因此才更有研究的价值
PSDom的开发环境--ExtendScript ToolKit:
在安装Adobe cs/cc系列时,会⾃动安装(我装的是CS5.0)
如果在Windows下开发,请见后缀名改为.jsx
如果使⽤.js后缀的话,可能会由Windows Scripting Host(WSH)来执⾏,⽽不是CS 脚本解析器。防冲突!
通过这两篇⽂章,希望能够让⼤家在PhotoShop中为所欲为
让我们来关注第⼀篇吧:
1)PS DOM(⽂档对象模型)⽤来操纵PS中的各个对象,可以使⽤AppleScript(mac专⽤),VBScript(windows专⽤),以及JavaScript(跨平台,本⽂档仅使⽤js代码来演⽰).
2)PS DOM中关键类图(竖线表⽰包含关系,且第三层开始的所有类都是所属于Document):
3)与绘制相关的对象:
⼆维绘制可以归类为三个绘制范畴:
1、位图/图像操作:
PS Dom通过Application.Document.Channel(通道)对象进⾏某个通道的数据操作(例如你可以分别对位图的四个通道R G B A 进⾏操作),这不是本⽂所关注的。
2、⽂本绘制:
PS Dom通过使⽤Application.Document.ArtLayer.TextItem进⾏⽂本的显⽰和相关操作。
由上⾯的寻址关系可以看到TextItem⽂本对象是被附加到PS中的⼀个Layer上的。
3、⽮量绘制:
PS Dom 通过使⽤:
Application.Document.PathItem
Application.Document.PathItem.SubPathItemApplication.Document.PathItem.SubPathItem.PathPoint
这三个类来进⾏相关操作的(实际上还有其他⼀些辅助类,具体我们在后⾯了解)
由上⾯的寻址关系可以看到PathItem路径对象是并没有像TextItem⼀样是被附加到PS中的⼀个Layer上的,⽽是独⽴于layer对象的。
4)JS运⾏调试环境和API参考⽂档:
安装好PhostShop CS5或更⾼的版本后,在你的PS安装⽬录下可以看到如下⽬录:
其中JavaScript Ref和Scripting Guide是你必须要进⾏查阅的参考,因为PS DOM开发⽹络上的信息⾮常少,所以这两篇⽂档是你基本唯⼀的依靠
Utilities ⽬录下:
scriptListener插件,⽤于PS Action录制时候将录制的步骤的js代码记录下来并输出到桌⾯⽂件。 是⼀
个⾮常重要的具有开发功能插件,以后会有专门⽂章,⽬前不关注。
Sample Scripts ⽬录下:
双击运⾏
psdomSample.png
⾥⾯都是js演⽰代码:
双击后跳出Yes/No Alert界⾯:
Yes会打开PS并运⾏代码,显⽰脚本运⾏后的效果
No会打开JS开发环境,可以进⾏脚本开发,修改,运⾏,debug等
5)常⽤的基础代码结构流程:
1、js代码⽂件的开始
//每个JS⽂件的开始部分,这些代码基本可以说是固定的
/
/ 如果有 #target photoshop,就直接打开Ps运⾏js脚本
//如果没有,则打开ps的脚本编辑器⽽不是直接在ps中运⾏
#target photoshop
// in case we double clicked the file
app.bringToFront();
2、单位标尺等数据的保存与恢复:
// 存储当前的状态
var startRulerUnits = app.preferences.rulerUnits;
var startTypeUnits = peUnits;
var startDisplayDialogs = app.displayDialogs;
//设置新的状态,我们使⽤像素来作为标尺和⽂档中各个对象的计量单位
/
/当然也可以设置其他计量单位,例如厘⽶,英⼨等
app.preferences.rulerUnits = Units.PIXELS;
peUnits = TypeUnits.PIXELS;
app.displayDialogs = DialogModes.NO;
//之所以这么做,是因为ps的开发是基于状态机模式的
//所有图形化操作基本都是状态机,opengl d3d
3、如果你PS打开了很多程序,希望只显⽰现在正在操作的那个⽂档,那么可以使⽤下⾯代码先关闭所有⽂档
// 关闭所有打开的⽂档
while (app.documents.length != 0)
{
app.activeDocument.close();
}
4、使⽤open全局函数,打开⼀个PSD⽂件,并将该⽂件设置为当前活动的Document
var  doc = open(File(app.path + "/⽰例/mytest.psd"));
app.activeDocument = buttonDoc;
5、 针对各种⽂档进⾏相关的操作
针对⽂档对象以及⽂档中的各个对象进⾏操作的代码是需要你来实现的!!
6、操作完⽂档后,需要恢复到原来的状态(恢复到开始时记录下来的状态值)
// 恢复到修改前的状态
app.preferences.rulerUnits = startRulerUnits;
peUnits = startTypeUnits;
app.displayDialogs = startDisplayDialogs;
/
/状态机恢复default状态
6. ⽂本操作(TextItem)
需求描述:
1、打印出ps所有的Font对象的信息,⽬的是为了了解TextFont对象主要属性: Family|name|postScriptName|style
function printAllInstalledTextFontInfo()
{
var allFonts = [];
for(var i = 0; i < app.fonts.length; i++)
{
var str = "{"+app.fonts[i].family+"|"+app.fonts[i].name+"|"
+app.fonts[i].postScriptName+"|"+app.fonts[i].style+"}";
allFonts.push (str);
}
alert(allFonts);
}
psdomFonts.png
2、不要从现有的PSD载⼊,⽽是从⽆到有通过代码创建⽂档,层等
//创建⼀个Document对象
var docRef = app.documents.add(400, 300, 72);
//创建⼀个ArtLayer对象
var newTextLayer = docRef.artLayers.add();
//注意:⼀个⽂本对象必须要依附于⼀个Layer对象,并且Layer的kind必须是TEXT类型
newTextLayer.kind = LayerKind.TEXT;
3、使⽤微软雅⿊并blod字体样式
//当设置为TEXT类型时,PS⾃动会创建⼀个TextItem对象给Layer,因此可以直接引⽤Item.font = "MicrosoftYaHeiUI-Blod";
//这⾥需要注意的是,TextItem.font的数据类型是字符串,该字符串是使⽤了TextFont  //对象中的postScriptName,这⼀点务必要注意。
//由这⾥看出,前⾯ printAllInstalledTextFontInfo函数的作⽤了,你可以打印出来,查  //postScriptName的名称,然后记住是⽤这个名称来设置字体name和style
4、绘制⽂字内容为"随风⽽⾏的PSDOM Demo"
//设置要显⽰的内容
5、设置⽂字的⼤⼩
6、⽂字颜⾊为红⾊(SolidColor对象)
var textColor = new SolidColor;
//这样就可以显⽰⽂字了
其他的⽂字相关属性请查阅⽂档
psdomText.png
7)路径操作(PathItem)---核⼼操作
1、先来⼀段⽰例代码,能够对PathItem有个⽐较直观的了解
我们编写⼀个函数,⽤来显⽰多边形:
function DrawPolygon() {
//PS是状态机,基于当前选中的状态进⾏操作
var doc = app.activeDocument;
js文字动画特效
//获取参数的数量,使⽤js可变参数
//因为多边形参数不确定,例如三⾓形,三个顶点,n边形,n个顶点
var y = arguments.length;
var i = 0;
var lineArray = [];
for (i = 0; i < y; i++) {
/
/创建⼀个PathPointInfo对象
//⾥⾯包含绘制点的相关信息
lineArray[i] = new PathPointInfo;
//多边形是凸包,没有任何曲线段表⽰,因此每个点都是CORNERPOINT类型    //如果是曲线的话,那么每个点的类似是SMOOTHPOINT
lineArray[i].kind = PointKind.CORNERPOINT;
//要绘制的点的坐标,来源于参数,类型为[x,y];
//对于⾮曲线来说,leftDirection = rightDirection=anchor
lineArray[i].anchor = arguments[i];
lineArray[i].leftDirection = lineArray[i].anchor;
lineArray[i].rightDirection = lineArray[i].anchor;
}
//到此处,所有的绘制点的信息都保存在lineArray数组中
//创建⼀个SubPathInfo对象
var lineSubPathArray = new SubPathInfo();
//ireSubPath指向了要绘制的顶点数据数组
//设置SubPathiInfo.closed为true,这样在strokePath时候,会⾃动封闭整个路径
//否则如果为false的话,那么会缺少最后⼀条线段,导致路径⾮封闭状态。lineSubPathArray.closed = true;
//设置ShapeOperation为Add模式,叠加模式,前景层直接覆盖到背景层上
//还有其他也写操作,可以理解为布尔操作,例如前景和背景取并集,交集,差集等lineSubPathArray.operation = ShapeOperation.SHAPEADD;
//创建⼀个PathItem对象,使⽤的是doc.pathItems.add⽅法
//注意,我们会发现是doc⽽不像TextItem是属于层对象的。
var myPathItem = doc.pathItems.add("myPath" , [lineSubPathArray]);
//调⽤PathItem的描边函数
//⽮量图形绘制可以分为边的绘制以及封闭形体的填充两种操作
//strokePath⽤来进⾏边的绘制
//fillPath则⽤来进⾏填充内容
myPathItem.strokePath(ToolType.PENCIL);
//绘制好后,将PathItem去除掉,由于已经描边渲染了,所有所有效果都输出到
//像素缓冲区了,因此不需要该PathItem了
//如果你需要后续进⾏顶点级别的操作的话,那你也可以保留着,不要remove掉
}
2、测试多边形绘制:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。