最近在修图,听说 Photoshop 可以用 JavaScript 写脚本,于是就去看了看怎么写,觉得自己作为一个前端,总不能看不懂代码吧。
目标是对选中的所有图层和组里的所有图层应用一个动作…需求很简单,也很常见吧。
查了一下代码,对特定的一个图层应用一个动作是这样的:
var doc = app.activeDocument;
doc.activeLayer = doc.artLayers.getByName("背景色");
app.doAction("foo", "foo_folder");
感觉已经没什么好害怕的了。但是发现这样只能选一个图层或者一个组,颇为不方便,要知道 PhotoShop 是可以同时选中多个图层的,而文档里也没有说明这个功能…
于是,在继续找下去的过程中,我看到了这玩意。
function getSelectedLayersIdx() {
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID('targetLayers'))) {
desc = desc.getList(stringIDToTypeID('targetLayers'));
var c = desc.count
var selectedLayers = new Array();
for (var i = 0; i < c; i++) {
try {
activeDocument.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Prpr"), charIDToTypeID("ItmI"));
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
try {
activeDocument.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(charIDToTypeID("ItmI")) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(charIDToTypeID("ItmI")));
}
var vis = app.activeDocument.activeLayer.visible;
if (vis == true) app.activeDocument.activeLayer.visible = false;
var desc9 = new ActionDescriptor();
var list9 = new ActionList();
var ref9 = new ActionReference();
ref9.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
list9.putReference(ref9);
desc9.putList(charIDToTypeID('null'), list9);
executeAction(charIDToTypeID('Shw '), desc9, DialogModes.NO);
if (app.activeDocument.activeLayer.visible == false) selectedLayers.shift();
app.activeDocument.activeLayer.visible = vis;
}
return selectedLayers;
};
………………
……………
…………
………
……
…
…那个,我盯着这堆玩意已经看了半个多小时了,有谁能看懂这堆玩意干了啥吗?
var getSelectedLayersIndex = function () {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(stringIDToTypeID('document'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID('targetLayers'))) {
desc = desc.getList(stringIDToTypeID('targetLayers'));
for (var i = 0, c = desc.count; i < c; i++) {
selectedLayers.push(desc.getReference(i).getIndex());
}
}
return selectedLayers;
};
进度: “看了几遍和没看一样” → “把不懂的代码删了也能正常用”
基本知道了它准备做一个图层顺序相关的动作,有可能是图层编组,但else中的代码好像毫无意义,整个动作似乎也并没有真的执行…
…虽然还是一脸茫然,但好像这样精简了一下养眼多了,在彻底弄懂之前先凑合用吧。
1
msg7086 2016-12-01 03:00:45 +08:00 1
我这有不少代码我已经来回看了几个月了,还有很多地方我完全看不懂到底干了啥。
半个小时,还好吧? |
2
hjc4869 2016-12-01 03:04:04 +08:00
这就算恶心了?…
|
3
wdhwg001 OP @msg7086 没有办法调试, API 不一样,也没有文档说明,而且这代码写的让人根本不知道发生了啥…
反正我一步一步从头到尾看了几遍了,然而依然对这玩意到底怎么实现的毫无头绪。 |
6
lslqtz 2016-12-01 04:00:35 +08:00
|
7
hehuozhao 2016-12-01 04:09:42 +08:00
可能是自动生成的代码?
|
8
q397064399 2016-12-01 06:38:32 +08:00
其实这种代码的问题显而易见,既没有向读者展示高层次的逻辑意图,又暴露了太多的操作实现细节
|
9
sagaxu 2016-12-01 06:45:38 +08:00 via Android
我这有大量长得很像但又并不完全一样的代码,一个方法写 500 行以上很普遍,几个开发者都离职了,我一边加功能的同时还要一边梳理重构。测试人员都没有,老代码单元测试覆盖率为零。这可是每天 pv 过亿,每天净利润六位数的项目。
|
10
ryanzyy 2016-12-01 07:18:02 +08:00
你需要 console.log 每个 API 的结果 然后尝试变一些参数 对照 PS 去理解
Good Luck |
11
pimin 2016-12-01 07:24:28 +08:00 via Android
你只知道 JS ,而不懂 PS API ,如果这都让你看懂了,大概知道怎么搬砖就盖摩天大楼咯?
|
12
valkyrja 2016-12-01 08:03:46 +08:00 via Android
不如做个动作简单粗暴
|
14
k9982874 2016-12-01 08:39:24 +08:00 via iPhone
adobe :我没给你压缩你说偷着乐吧
|
15
harry890829 2016-12-01 08:42:21 +08:00
习惯就好了,我现在处理的项目,什么利用 if 分支写死的变量,手动拼 json ,手动解析 json 什么的,简直不忍直视
|
16
everyx 2016-12-01 08:47:32 +08:00 via Android
Photoshop 是有 api 文档的,如果需要使用文档中未提及的操作,就需要使用另一个动作到处代码的工具,打开 PS 执行一个动作,他就会生成对应的代码,直接替换参数用,这些代码的确会看不懂
|
17
bigbyto 2016-12-01 08:55:31 +08:00 1
见过 switch 套 switch 中间还有 while 循坏和 if 判断的;还见过写 android 定义了 800 多行变量;这种看起来还行。
|
18
wyntergreg 2016-12-01 08:57:20 +08:00
你这被子还长着呢,以后还有的是更恶心的代码
|
19
aristotll 2016-12-01 08:59:29 +08:00
关键都是些 API
通用的 JavaScript 知识对阅读代码无效 |
20
Ouyangan 2016-12-01 09:03:42 +08:00
太年轻了 , 来我这看看一个屏幕看不完的 if,else
|
21
zwik 2016-12-01 09:28:33 +08:00
上次像写个 ps 的外挂插件,翻了几个文档,完全没有头绪,看来看出都是以 ps 内置扩展文件.8x 的形式出现的插件开发,外挂插件的说明感觉看到关键的地方,然后一下又扯得很宽泛...
最后就写了个简单的 ps js 的脚本 函数的说明能不能详细点,返回值都没有 |
22
liuxu 2016-12-01 09:29:25 +08:00
我就看到外部有个 var selectedLayers = new Array();,然后 if 里面又有一个。。
|
23
t2doo 2016-12-01 09:30:01 +08:00
这就最恶心啦,年轻人你还 too young ,看哥给你写一段。。。
|
25
yoke123 2016-12-01 09:43:11 +08:00
这点算什么 too young too simple ( doge 脸)
|
26
songz 2016-12-01 09:45:42 +08:00 via Android
这属于 extended script,用了 Adobe 分给 ps 的接囗,写法还是通 js 的
|
27
itqls 2016-12-01 09:50:28 +08:00
无非是循环找各种图层啥的
|
28
xiaolai123 2016-12-01 09:53:08 +08:00
还好吧 我看别人的代码感觉都知道它们在干吗
|
31
cppgohan 2016-12-01 09:54:48 +08:00
太年轻:)
|
32
weberCd 2016-12-01 09:55:03 +08:00
这就恶心了?那你是没看过我的代码
|
33
GOOD21 2016-12-01 09:55:47 +08:00
太年轻了 , 来我这看看一个屏幕看不完的 if,else
|
34
ihuzhou 2016-12-01 10:00:22 +08:00
真实的故事, rightSomeThing = LeftSomeThing()。。前人挖坑,后人掉坑
|
36
yangxiongguo 2016-12-01 10:04:23 +08:00
ps 不熟看这些代码就是噩梦
|
37
Garnett0328 2016-12-01 10:04:33 +08:00 via iPad
楼主太年轻
|
38
jarlyyn 2016-12-01 10:04:50 +08:00 3
呵呵,有本事看我当年写的代码。
真的看懂的话别忘记告诉我下这些代码是干啥的-_____- |
39
jukka 2016-12-01 10:07:41 +08:00
不算 try exception 圈复杂度才 4 的代码,哪里恶心了。
|
40
smallpath 2016-12-01 10:19:52 +08:00
ps 的标准 api 文档都找不到, ame 特么还没文档呢,楼上说操作实现细节的, ps 通篇都是类似浏览器的 dom 操作,要不暴露只能自己再造个 adobe 的 jQuery ,哦对了, Object.prototype.watch 可以截取 get set ,要不要再造个 mvvm ?
|
41
mhycy 2016-12-01 10:28:37 +08:00
|
42
yanzixuan 2016-12-01 10:30:25 +08:00
搞不好是机器自动生成的代码。当年玩 FPGA 的时候看混淆过的 VERILOG 的路过。。。
|
43
jyf 2016-12-01 10:40:45 +08:00
这代码挺厚道的 已经把意图弄到命名上了 看变量名基本能看出来是在干啥
你要碰到那种 i p 变量满天飞的 那才真是生不如死呢 这个代码最大的问题只是没有把片段分离出来导致一个函数太长了 但是这只是 better 追求 |
44
shellcodecow 2016-12-01 10:40:55 +08:00
还好吧 除了命名以外..
|
45
hoythan 2016-12-01 10:42:45 +08:00 via iPhone
慢慢看下去逻辑还是很明显的
|
46
loryyang 2016-12-01 10:53:41 +08:00
这代码很难懂吗?我觉得这个代码已经质量不错了,函数、变量的命名相当规范,你试想一下里面的变量全部叫做 ab, c, xx, tmp, str 的时候,你是怎样的感觉?
|
47
BigDipper7 2016-12-01 11:09:13 +08:00
擦,看来我的承受能力还不错,我上次还看到用拼音做 annotation 的,还有什么变量名 abcd 的,你这个算是好的了好么, PS 我的也是没有文档的,啥也没有
|
48
zongwan 2016-12-01 11:19:20 +08:00
只能用 alert 调试 这点不太方便
api 官网是找的到文档的 可以下载别人写的 plugins 做参考 然后再使用 小动作 使用 fireworks 写脚本会更方便(不过这玩意过时了 被 adobe 抛弃了) |
49
hector 2016-12-01 11:21:27 +08:00
我们 20 个程序员两年的项目,到现在没有一行注释,这算个啥
|
50
zongwan 2016-12-01 11:23:36 +08:00
http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/photoshop/pdfs/photoshop-cc-scripting-guide-2015.pdf
脚本 + 自己写的 plugins 可以自动化很多事情 |
51
sup 2016-12-01 11:25:47 +08:00
我懂你的苦
|
53
kaifeii 2016-12-01 11:35:56 +08:00
见过业务逻辑全写到 sql 里,跑程序就是跑 sql 。……跨语言、跨平台性 MAX 。
|
54
j4fun 2016-12-01 11:40:54 +08:00
这就恶心啦?。。。还差的远那。。。我们有 C 写的各路回调( N 层),各种强制类型转换,各种名字一样,其实完全不同含义的形参。。各种一个函数上千行的代码。。你要来试试不 :)
|
55
mazyi 2016-12-01 11:59:56 +08:00
51 楼有文档???楼主的救星啊哈哈哈。
|
56
zhuangzhuang1988 2016-12-01 12:19:05 +08:00
这还恶心??
另外 ps 可以调试的 |
57
jason19659 2016-12-01 14:12:16 +08:00
```
function a(a) { var f = 1 << a[27] | 1 << a[28] | 1 << a[29] | 1 << a[30] | 1 << a[31] | 1 << a[32] | 1 << a[33]; if (16 <= f) return ! 1; if (2 == (f & 3) && 2 == a[0] * a[8] * a[9] * a[17] * a[18] * a[26] * a[27] * a[28] * a[29] * a[30] * a[31] * a[32] * a[33] || !(f & 10) && 7 == (2 == a[0]) + (2 == a[1]) + (2 == a[2]) + (2 == a[3]) + (2 == a[4]) + (2 == a[5]) + (2 == a[6]) + (2 == a[7]) + (2 == a[8]) + (2 == a[9]) + (2 == a[10]) + (2 == a[11]) + (2 == a[12]) + (2 == a[13]) + (2 == a[14]) + (2 == a[15]) + (2 == a[16]) + (2 == a[17]) + (2 == a[18]) + (2 == a[19]) + (2 == a[20]) + (2 == a[21]) + (2 == a[22]) + (2 == a[23]) + (2 == a[24]) + (2 == a[25]) + (2 == a[26]) + (2 == a[27]) + (2 == a[28]) + (2 == a[29]) + (2 == a[30]) + (2 == a[31]) + (2 == a[32]) + (2 == a[33])) return ! 0; if (f & 2) return ! 1; var q = a[0] + a[3] + a[6], e = a[1] + a[4] + a[7], n = a[9] + a[12] + a[15], d = a[10] + a[13] + a[16], r = a[18] + a[21] + a[24], k = a[19] + a[22] + a[25], p = (q + e + (a[2] + a[5] + a[8])) % 3; if (1 == p) return ! 1; var l = (n + d + (a[11] + a[14] + a[17])) % 3; if (1 == l) return ! 1; var s = (r + k + (a[20] + a[23] + a[26])) % 3; if (1 == s || 1 != (2 == p) + (2 == l) + (2 == s) + (2 == a[27]) + (2 == a[28]) + (2 == a[29]) + (2 == a[30]) + (2 == a[31]) + (2 == a[32]) + (2 == a[33])) return ! 1; q = (1 * q + 2 * e) % 3; e = g(a, 0); n = (1 * n + 2 * d) % 3; d = g(a, 9); r = (1 * r + 2 * k) % 3; a = g(a, 18); var sb = f & 4 ? !(p | q | l | n | s | r) && c(e) && c(d) && c(a) : 2 == p ? !(l | n | s | r) && c(d) && c(a) && b(q, e) : 2 == l ? !(s | r | p | q) && c(a) && c(e) && b(n, d) : 2 == s ? !(p | q | l | n) && c(e) && c(d) && b(r, a) : !1 return sb } ``` 头疼 |
58
mhycy 2016-12-01 14:20:14 +08:00
@jason19659 谁家的验证代码?看起来还行
|
59
Caratpine 2016-12-01 15:03:14 +08:00
这段代码至少在风格少还是比较清晰吧。哎,遇到风格千奇百怪的代码才让人头大。。
|
60
Thoxvi 2016-12-01 15:12:56 +08:00 via Android
PS 不是有个录制功能吗…
|
61
soland 2016-12-01 15:19:14 +08:00
@jason19659 哈哈哈哈
|
62
NCE 2016-12-01 15:33:02 +08:00
用到递归了吧?如果有子文件夹之类的,很全面了
|
63
wdhwg001 OP |
65
innoink 2016-12-01 18:00:40 +08:00
那些史前流传下来不知道改了几遍的 C 代码才叫一个恶心
|
66
loveuqian 2016-12-01 18:15:52 +08:00 via iPhone
谁把 oc 那个 if 判断的图贴一下
|
67
gouchaoer 2016-12-01 18:19:32 +08:00
缺乏类型的脚本语言就这样咯
|
68
holy_sin 2016-12-01 18:45:27 +08:00
最起码还有代码缩进啊
|
69
muyege 2016-12-01 19:47:06 +08:00
这辈子还长,别这么诅咒自己
|
70
znoodl 2016-12-01 22:02:18 +08:00
见过几百行代码很多 if ,中间是缩进几十行的 tab ,代码像一条龙,那感觉。。。
|
71
yangff 2016-12-01 22:17:06 +08:00
嘻嘻,比起 jazz 好多了
|
72
zhuangzhuang1988 2016-12-01 22:18:38 +08:00
去 看下 matlab 代码比这些短
看一星期都不一定看得懂 |
73
huntzhan 2016-12-02 00:02:23 +08:00
你对恶心一无所知(跑
|
74
thedarkside 2016-12-02 09:28:55 +08:00
没有那么难懂吧~
|
75
DingSoung 2016-12-02 20:18:38 +08:00
你都用自动生成代码了 那代码还有可读性么
|