- 在线时间
- 1579 小时
- 专家
- 0
- UID
- 204516
- 注册时间
- 2005-9-5
- 帖子
- 6131
- 精华
- 4
- 积分
- 16516
- 居住地
- 浙江省 杭州市
- 离线
- 578 天
专长: 网页设计,UI设计
- 帖子
- 6131
- 体力
- 15919
- 威望
- 105
- 居住地
- 浙江省 杭州市
|
发表于 2008-5-14 18:30:21
|显示全部楼层
接下来我们开始编写脚本,为了通俗,这一步主要只是谈谈思路
首先测试单个文件,
脚本大致需要执行如下步骤:
1、 移动到最底层
2、 向上移动一层,利用 activeLayer.bounds 记录层范围坐标,并把坐标记录下来
3、 反复执行第2步,直到最顶层
4、 输出记录
有了以前一些脚本的经验,实现上面这个功能没有碰到什么难度,很容易搞定。
然后就是批量处理了,借鉴xiexienila 的变更尺寸脚本(原帖地址:http://bbs.blueidea.com/thread-2831563-3-7.html),该脚本已经有完善的批量打开、保存处理模块。局部Copy后稍加修改,就让我们的脚本实现了如下功能:
1、 用户选择待处理文件夹
2、 获取该文件夹下所有文件
3、 打开一个文件,获取并记录所有需要的坐标,关闭不保存
4、 重复第3步,直至处理完所有文件
5、 输出记录
测试成功后,想到:既然已经动用脚本获取了所有坐标,索性把两张不同的图片也输出保存好了。于是添加了一个保存位置选择。
并对单个文件内的操作作了修改:
1、 移动到最底层
2、 打开最底层智能对象
3、 另存智能对象为jpg文档(xxx_1)
4、 隐藏智能对象里的最上层,也就是我们修改过的那层
5、 再次另存智能对象为jpg文档(xxx_0)
6、 不保存关闭智能对象(回到原文档)
7、 向上移动一层,利用 activeLayer.bounds 记录层范围坐标,并把坐标记录下来
8、 反复执行第7步,直到最顶层
这样不但记录了坐标数据,还顺便把智能对象里面的两个层都输出为jpg图像了。
后来,由于第二张图片和第一张图片很多相同的地方,导致游戏文件体积较大,所以想了一个解决办法,就是把相同的部分用黑色挡住,只保留不同的地方,这样jpg就小很多。也许是个笨办法吧,毕竟不太清楚别人怎么做的,这里只是给大家说说思路罢了。
于是再次修改单个文件内的操作部分
1、 移动到最底层
2、 向上移动一层,利用activeLayer.bounds 记录层范围坐标,并把坐标记录下来
3、 反复执行第2步,直到最顶层
4、 再次回到最底层
5、 打开最底层智能对象
6、 利用记录的坐标,建立选区(增加模式),全部选区增添完后,反选
7、 填充黑色(这时候是填充在智能对象内部最上层上,也就是我们修改过的那层)
8、 另存为智能对象为jpg文档(xxx_1)
9、 隐藏当前图层
10、 再次另存智能对象为jpg文档(xxx_0)
11、 不保存关闭智能对象(回到原文档)
这样我们就给修改过的图像增添了一个黑色部分,挡住了没动过的地方,只留下了差异处
为了减少jpg 保存可能对边缘造成的影响,所以黑色部分的填充范围缩小了2像素。
后来为了修改方便,索性在面板上放了一个位置,可以手动输入缩小量。
为了程序调用方便,脚本还顺便实现其他一些功能:
比如把文件名作些规范处理:按照数字大小排序文件(否则打开顺序会是1、11、12、2、21这样),并且把1.psd 、2.psd 之类的记录为 0001、0002;
用简单正则替换去掉坐标记录转换为字符串后的“ px”单位等等。
为了处理时对进度有个掌握,脚本界面上还放了进度条。
最后,发现有时候不需要重新生成图像,只需要获取坐标。又在界面上加了一个 “仅查询坐标,不生成图片”的选项。如果勾选,就会跳过保存的步骤,以节省时间。
以上的过程,最终就是如下这个脚本程序,处理我近百张图片也就3分多的样子,手工的话又容易出错又慢,程序的优势就这样体现出来了。
以后要修改、调整,只要修改psd文档,再用脚本重新生成 就很快完成工作。两个多小时的编写调试还是值得的
- #target photoshop
- app.bringToFront();
- res ="dialog { \
- text:'找茬数据专用',\
- group: Group{orientation: 'column',alignChildren:'left',\
- folderO:Group{ orientation: 'row', \
- b: Button {text:'待处理文件夹', properties:{name:'open'} ,helpTip:'选择您需要处理的文件所在的文件夹'},\
- s: EditText { text:'', preferredSize: [360, 20] },\
- },\
- folderS:Group{ orientation: 'row', \
- b: Button {text:'输出图像至', properties:{name:'save'} ,helpTip:'选择您处理好的文件要保存至的文件夹'},\
- s: EditText { text:'', preferredSize: [360, 20] },\
- },\
- meng:Group{ orientation: 'row', \
- c:Checkbox { text:' 启用黑色蒙版'} ,\
- s: StaticText { text:'| 蒙版收缩量(单位px):' }, \
- e: EditText { text:'2', preferredSize: [20, 18]},\
- },\
- Quality: Group { orientation: 'row', \
- c:Checkbox { text:' 仅查询坐标,不生成图片'} ,\
- s: StaticText { text:'| 生成JPG的压缩质量:' }, \
- d: DropDownList { alignment:'left', itemSize: [26,14] },\
- }, \
- gg: Group{orientation: 'column',alignChildren:'left' },\
- timeline:Progressbar{bounds:[0,0,400,10] , minvalue:0,maxvalue:100}\
- aa: Button { text:'START'}, \
- }\
- }";
- var mengPoint="";
- var mengColor =new SolidColor;
- mengColor.rgb.red =0;
- mengColor.rgb.green =0;
- mengColor.rgb.blue =0;
-
- win = new Window (res);
- win.myText = win.group.gg.add("edittext",[0,0,500,300],'~~~',{multiline:true, readonly:false});
- for (i=0;i<13;i++){ //初始化jpeg质量下拉
- win.group.Quality.d.add("item", i );
- }
- win.group.Quality.d.items[7].selected=true;
- function lyFoot() { // 选中最下层
- var id553 = charIDToTypeID( "slct" );
- var desc88 = new ActionDescriptor();
- var id554 = charIDToTypeID( "null" );
- var ref95 = new ActionReference();
- var id555 = charIDToTypeID( "Lyr " );
- var id556 = charIDToTypeID( "Ordn" );
- var id557 = charIDToTypeID( "Back" );
- ref95.putEnumerated( id555, id556, id557 );
- desc88.putReference( id554, ref95 );
- var id558 = charIDToTypeID( "MkVs" );
- desc88.putBoolean( id558, false );
- executeAction( id553, desc88, DialogModes.NO );
- }
- function lyUp(){ //选中上一层
- var id559 = charIDToTypeID( "slct" );
- var desc89 = new ActionDescriptor();
- var id560 = charIDToTypeID( "null" );
- var ref96 = new ActionReference();
- var id561 = charIDToTypeID( "Lyr " );
- var id562 = charIDToTypeID( "Ordn" );
- var id563 = charIDToTypeID( "Frwr" );
- ref96.putEnumerated( id561, id562, id563 );
- desc89.putReference( id560, ref96 );
- var id564 = charIDToTypeID( "MkVs" );
- desc89.putBoolean( id564, false );
- executeAction( id559, desc89, DialogModes.NO );
- }
- function openSm() { //打开智能对象
- var id216 = stringIDToTypeID( "placedLayerEditContents" );
- var desc43 = new ActionDescriptor();
- executeAction( id216, desc43, DialogModes.NO );
- }
- function lyHidden(){ //隐藏当前图层
- var id217 = charIDToTypeID( "Hd " );
- var desc44 = new ActionDescriptor();
- var id218 = charIDToTypeID( "null" );
- var list1 = new ActionList();
- var ref24 = new ActionReference();
- var id219 = charIDToTypeID( "Lyr " );
- var id220 = charIDToTypeID( "Ordn" );
- var id221 = charIDToTypeID( "Trgt" );
- ref24.putEnumerated( id219, id220, id221 );
- list1.putReference( ref24 );
- desc44.putList( id218, list1 );
- executeAction( id217, desc44, DialogModes.NO );
- }
- function sm(name) { //保存结果图像
- lyFoot();
- openSm();
- var smDoc=app.activeDocument;
- if (win.group.meng.c.value) meng(smDoc);
- var saveFolder = win.group.folderS.s.text+"/";
- saveOptions = new JPEGSaveOptions();
- saveOptions.quality =win.group.Quality.d.selection.index;; //获取jpg压缩质量
- smDoc.saveAs(new File(saveFolder + name + "_1.jpg"),saveOptions, true,Extension.LOWERCASE);
- lyHidden();
- smDoc.saveAs(new File(saveFolder + name + "_0.jpg"),saveOptions, true,Extension.LOWERCASE);
- smDoc.close(SaveOptions.DONOTSAVECHANGES);
- }
- function selectBounds(name,a,b,c,d) { //做选区
- app.activeDocument.selection.select([[a, b],[ a, d ], [c, d], [ c, b]],SelectionType.EXTEND);
- }
- function meng(smDoc) { //添加蒙版
- nowPoint=mengPoint.split(",");
- for (var i=0;i<nowPoint.length-4;i+=4){
- selectBounds(smDoc,nowPoint[i],nowPoint[i+1],nowPoint[i+2],nowPoint[i+3],)
- }
- // ==================================扩展n像素
- var id32 = charIDToTypeID( "Expn" );
- var desc5 = new ActionDescriptor();
- var id33 = charIDToTypeID( "By " );
- var id34 = charIDToTypeID( "#Pxl" );
- desc5.putUnitDouble( id33, id34, Number(win.group.meng.e.text) );
- executeAction( id32, desc5, DialogModes.NO );
- // ==================================反选
- var id35 = charIDToTypeID( "Invs" );
- executeAction( id35, undefined, DialogModes.NO );
- //
- smDoc.selection.fill(mengColor); //填充蒙版色
- }
- // 打开文件夹的操作
- var folderOpen=win.group.folderO
- var folderSave=win.group.folderS
- folderOpen.b.onClick = function() {
- var defaultFolder = folderOpen.s.text;
- var testFolder = new Folder(defaultFolder);
- if (!testFolder.exists) {
- defaultFolder = "~";
- }
- var selFolder = Folder.selectDialog("选择待处理文件夹", defaultFolder);
- if ( selFolder != null ) {
- folderOpen.s.text = selFolder.fsName;
- folderOpen.s.helpTip = selFolder.fsName.toString();
- }
- }
- folderSave.b.onClick = function() {
- var defaultFolder = folderSave.s.text;
- var testFolder = new Folder(defaultFolder);
- if (!testFolder.exists) {
- defaultFolder = "~";
- }
- var selFolder = Folder.selectDialog("选择要储存至的文件夹", defaultFolder);
- if ( selFolder != null ) {
- folderSave.s.text = selFolder.fsName;
- folderSave.s.helpTip = selFolder.fsName.toString();
- }
- }
- win.group.aa.onClick=function(){
- var myText="";
- var openFolder = Folder(win.group.folderO.s.text);
- var fileList = openFolder.getFiles() //获取open文件夹下所有文件
- win.group.timeline.value =0;
- var k=100/fileList.length;
-
- //调整文件顺序,按数字大小排序
- fileList.sort(function compare(a,b){return Number(a.name.substring(0, a.name.length-4))-Number(b.name.substring(0, b.name.length-4));})
- //
- for (i=0;i<fileList.length;i++){
- if (fileList[i] instanceof File && fileList[i].hidden == false){ //不处理隐藏文件
- var docRef =open(fileList[i]);
- var nowName =docRef.name.substring(0, docRef.name.length-4);
- while (nowName.length<4) {
- nowName ="0"+nowName;
- }
- myText +=nowName+",";
- mengPoint="";
- lyFoot();
- for (j=1;j<docRef.layers.length;j++){
- lyUp();
- myText+=docRef.activeLayer.bounds+",";
- mengPoint+=docRef.activeLayer.bounds+",";
- }
- if (!win.group.Quality.c.value) sm(nowName);
- docRef.close(SaveOptions.DONOTSAVECHANGES);
- myText +="\r\n";
- }
- win.group.timeline.value =win.group.timeline.value+k;
- }
- var re = / px/g; //要替换的“ px”
- win.myText.text=myText.replace(re, "");
- }
- //////////////
- win.center();
- win.show();
复制代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在编写脚本的时候,不能不提到的一个辅助工具就是“脚本侦听程序”
这个东西就在 cs3 安装目录下面的“脚本指南/实用工具”里面(英文版在 Scripting Guide\Utilities\)
如果把它拷贝到“增效工具/自动”目录下(英文版为 Plug-Ins\Automate),再重新启动ps。
你的ps就相当于安装了一个“窃听器”,会把你所有的操作步骤像录制动作一样录制为脚本。
只要你有可记录的动作,它就在桌面生成 “ScriptingListenerJS”、“ScriptingListenerVB” 两个文本文件。其实就是 javascript 和 vbscript 两种规则记录的动作。
虽然不像手工书写的代码易于理解和修改,但是很多直接操作的步骤都可以拷贝来用。
比如说上面的 “移动到最底层”“选中上一层”“隐藏当前层”“打开智能对象”“扩展n像素”“反选”等等动作就是通过脚本侦听录制下来 直接拷贝过来的。
再结合自己的编写的其他逻辑语句,很容易写出你想要的东西。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
最后,希望有点编程基础又有兴趣的朋友,
在处理重复、量大或者经常碰到的工作的时候,多多挖掘ps的潜力。
其实写一个简单的针对性脚本或者动作 并不是很难哦 ^_^
[ 本帖最后由 wonton 于 2008-5-17 09:36 编辑 ] |
附件: 你需要登录才可以下载或查看附件。没有帐号?注册
|