最近在修图,听说 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 ![]() 我这有不少代码我已经来回看了几个月了,还有很多地方我完全看不懂到底干了啥。 半个小时,还好吧? |
![]() | 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 ![]() 见过 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 DiagnosticError 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 ,看哥给你写一段。。。 |
![]() | 24 DiagnosticError 2016-12-01 09:30:08 +08:00 r#21 @zwik 网上发帖求助 人家又一个劲地让你去看文档,我勒个去 我能搞掂这个文档,我闲着蛋疼去求助你们 |
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 ![]() 呵呵,有本事看我当年写的代码。 真的看懂的话别忘记告诉我下这些代码是干啥的-_____- |
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 yanzxuan 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 PRO 51 楼有文档???楼主的救星啊哈哈哈。 |
![]() | &nbp; 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 你都用自动生成代码了 那代码还有可读性么 |