PhotoShop CS的插件开发其实挺简单的,做个原理性的介绍
1、首先,需要从Adobe官网上下载开发工具包(http://www.adobe.com/downloads/?promoid=KAWQL),里面有各种对应版本的的开发包
2、下载解包后,建立目录,有3个文件夹:
documentation:帮助文档,里面都英文,可以细细品味,建议入门者可以忽略,反正我觉得比较难懂
photoshopapi:API库,开发需要调用到的库,不要修改里面的代码
samplecode:例子程序,可以随意地将里面的例子改造成你想要的插件
3、打开samplecode,可以看到各种分类文件夹,对应不同的插件功能,
其中Output文件侠是用来当作编译输出目录的,
入门首先需要学习两个插件:getter 和 listener,它们在samplecode\automation目录下
4、getter插件:打开samplecode\automation\getter\win\getter.sln,编译生成插件,放到PS插件目录下试下(你也可以将Output里插件目录设置为PS的增效工具目录),运行PS->文件->自动->getter,然后你会发现桌面上多了个getter.log,该插件的主要目的就是把你当前在PS里打开的文件、图层信息及函数调用方法输出到log里去,所以当你不知道如何获取某个信息时,查找getter.log里对应的函数
5、listener插件:该插件的作用是监听PS里的大部分操作和事件的函数调用过程,并输出到桌面上的listerner.log里,比如你要复制剪切某一图层,而且不知道如何用函数实现它的时候,先使用listener插件,打开PS对图层进行一次复制剪切操作,然后打开listener.log,代码就在那
6、其它的一些插件:可以照着它的英文名大概理解其意思
7、框架:
每个插件里都有个AutoPluginMain,其实就是DLL入口,所谓的插件其实就是个DLL,找几个插件,在AutoPluginMain里加个断点,跟踪一下,看看这些插件都干了些什么
有些插件自带弹框界面,可以用资源管理器编辑,用DialogBoxParam创建你自定义的界面,参考listener里的DoUI函数,makenew里的DoAbout等
几乎所有的API函数都会返回一个SPErr,表示函数调用正确与否
所有的操作都需要有个PIActionDescriptor,可以创建(sPSActionDescriptor->make())或获取(PIUGetInfo())
sPSActionDescriptor是一个接口指针,可以从中获取PIActionDescriptor信息(下面简称desc)以及执行一些操作
sPSActionReference是一个接口指针,用来封装一些信息到desc中,(下面简称refer)
sPSActionControl是一个接口指针,用来Play各种事件
如果要获取信息,可以使用PIUGetInfo系列函数(在PIUGet.h中定义)
8、例子:
获取文件信息:
[cpp] view plaincopyprint?SPErr error = kSPNoError;
int numDocuments = 0;
error = PIUGetInfo(classApplication, keyNumberOfDocuments, &numDocuments, NULL); // 获取当前PS里打开的文件数量
......
Auto_Desc descDoc(false); // 这是一个PIActionDescriptor类型的智能指针,这样就不用但心释放问题
error = PIUGetInfoByIndex(i, classDocument, 0, &descDoc, 0); // 获取第i个文件的desc,然后再从该desc里获取具体的图层、颜色、alpha等信息
......
double dValue = 0;
DescriptorUnitID unitID = unitDistance;
error = sPSActionDescriptor->GetUnitFloat(descDoc.get(), keyWidth, &unitID, &dValue); // 获取文件的宽度(即画布大小),同理还有个keyHeight
SPErr error = kSPNoError;
int numDocuments = 0;
error = PIUGetInfo(classApplication, keyNumberOfDocuments, &numDocuments, NULL); // 获取当前PS里打开的文件数量
......
Auto_Desc descDoc(false); // 这是一个PIActionDescriptor类型的智能指针,这样就不用但心释放问题
error = PIUGetInfoByIndex(i, classDocument, 0, &descDoc, 0); // 获取第i个文件的desc,然后再从该desc里获取具体的图层、颜色、alpha等信息
......
double dValue = 0;
DescriptorUnitID unitID = unitDistance;
error = sPSActionDescriptor->GetUnitFloat(descDoc.get(), keyWidth, &unitID, &dValue); // 获取文件的宽度(即画布大小),同理还有个keyHeight
获取图层信息:
[cpp] view plaincopyprint?DescriptorTypeID keyLayerSection = 0;
DescriptorTypeID keyLayerStart = 0;
DescriptorTypeID keyLayerEnd = 0;
DescriptorTypeID keyBounds = 0;
PIActionDescriptor descLayer = 0;
int32 numlayers = 0;
error = PIUGetInfoByID(docID, classDocument, keyNumberOfLayers, &numlayers, 0); // 根据docID(也可以用Index)来获取图层数量
error = PIUGetInfoByIndex(i, classLayer, 0, &descLayer, NULL); // 当前选中图片文件(指获取焦点)的第i个图层信息
sPSActionControl->StringIDToTypeID("layerSection", &keyLayerSection);
sPSActionControl->StringIDToTypeID("layerSectionEnd", &keyLayerEnd); // 图层分组的结束标记
sPSActionControl->StringIDToTypeID("layerSectionStart", &keyLayerStart); // 图层分组的开始标记
sPSActionControl->StringIDToTypeID("bounds",&keyBounds
error = sPSActionDescriptor->GetEnumerated(descLayer, keyLayerSection, &retTypeID, &retEnumID); // 获取该图层类型,可能是个分组文件夹
if (error || retEnumID == keyLayerEnd || retEnumID == keyLayerStart)</
; // 遇到分组开始和结束标记,该descLayer不是真正的图层
char strName[256
error = sPSActionDescriptor->GetString(descLayer, keyName, strName, 255); // 获取图层名
error = PIUGetSingleItemFromDescriptor(descLayer, keyBounds, &descKey, &descClass); // 获取图层大小
double top = 0, left = 0, bottom = 0, right = 0;
// 获取具体的图层大小值
error = sPSActionDescriptor->GetFloat(descKey, keyLeft, &left);
error = sPSActionDescriptor->GetFloat(descKey, keyRight, &right);
error = sPSActionDescriptor->GetFloat(descKey, keyTop, &top);
error = sPSActionDescriptor->GetFloat(descKey, keyBottom, &bottom);
DescriptorTypeID keyLayerSection = 0;
DescriptorTypeID keyLayerStart = 0;
DescriptorTypeID keyLayerEnd = 0;
DescriptorTypeID keyBounds = 0;
PIActionDescriptor descLayer = 0;
int32 numlayers = 0;
error = PIUGetInfoByID(docID, classDocument, keyNumberOfLayers, &numlayers, 0); // 根据docID(也可以用Index)来获取图层数量
error = PIUGetInfoByIndex(i, classLayer, 0, &descLayer, NULL); // 当前选中图片文件(指获取焦点)的第i个图层信息
sPSActionControl->StringIDToTypeID("layerSection", &keyLayerSection);
sPSActionControl->StringIDToTypeID("layerSectionEnd", &keyLayerEnd); // 图层分组的结束标记
sPSActionControl->StringIDToTypeID("layerSectionStart", &keyLayerStart); // 图层分组的开始标记
sPSActionControl->StringIDToTypeID("bounds",&keyBounds
error = sPSActionDescriptor->GetEnumerated(descLayer, keyLayerSection, &retTypeID, &retEnumID); // 获取该图层类型,可能是个分组文件夹
if (error || retEnumID == keyLayerEnd || retEnumID == keyLayerStart)</
; // 遇到分组开始和结束标记,该descLayer不是真正的图层
char strName[256
error = sPSActionDescriptor->GetString(descLayer, keyName, strName, 255); // 获取图层名
error = PIUGetSingleItemFromDescriptor(descLayer, keyBounds, &descKey, &descClass); // 获取图层大小
double top = 0, left = 0, bottom = 0, right = 0;
// 获取具体的图层大小值
error = sPSActionDescriptor->GetFloat(descKey, keyLeft, &left);
error = sPSActionDescriptor->GetFloat(descKey, keyRight, &right);
error = sPSActionDescriptor->GetFloat(descKey, keyTop, &top);
error = sPSActionDescriptor->GetFloat(descKey, keyBottom, &bottom);
暂时先写这么多,还有事件调用,对图层操作等等,其本上看listener.log和getter.log都能获取源代码,然后就是发挥想像力,自由组合,拼出想要的插件功能了。