标签:style blog color java os 使用 io 文件 for
背景:身在一个有实业的电商公司,设计部的妹子们总是会有做不完的商品图片,当然了,要是做点有技术含量的美化工作也罢,但是最近她们很是无聊,总是要做一些重复性的工作,就比如如题所说的,图片量产,量产什么呢?价格牌。。。这东西很没意思哎!就是给你一个模板,然后你自己把模板原来的文字图片换掉就行了,再排一下版,纯体力劳动好么!博主做过一阵子的对日外包工作,深知她们的痛苦,如果说某些对日外包的程序猿是人肉转码器的话,那么设计部的妹子们现在就成了。。算了,词就不说了,太残酷了
========================================炫炸天的分割线========================================
线索:针对背景交代的情况,BOSS给了我一个提示:PS脚本,顺着这个线索,我就进行了一系列调查,我分别做了@#¥%……&*()的努力,简而言之,photoShop自带的开发文档帮了我大忙,文档位于Adobe Photoshop CS5\Scripting\Documents\,参考了Photoshop CS5 Scripting Guide.pdf和Photoshop CS5 JavaScript Ref.pdf,当然了,自带的文档貌似还不能完全满足我的需求,我还自己下载了一个JavaScriptToolsGuide_CS5.pdf,抱着这三个文档啃了又啃,总归算是完成了这样一个量产工具。
========================================酷炸天的分割线========================================
开发思路:既然是量产工具,那么他的工作流程应该是这样的,1工具读了一个文件,文件包含了所有产品的信息,2循环抽取每一个商品的信息,生成图片并保存,3循环完毕,给出一个提示,OK,大概思路就是这样了,然后接下来就是顺着这个思路啃文档了。。。
========================================拽炸天的分割线========================================
代码如下:
1 //测试版本:PhotoShop CS5 12.0.3 x32 通过 2 //作者:Duke 3 //测试完结日期:2014/08/24 4 5 priceCardGenerator() 6 7 function priceCardGenerator(){ 8 9 /** 10 * 定义统一的赋值变量 11 */ 12 var title //标题 13 var liwaiCode //里外编码 14 var priceTitle //售价标题,为了方便替换 15 var price //售价 16 var sample //价格符号 17 var fiveAssureFeeTitle //五包费用标题,为方便替换 18 var fiveAssureFee //五包费用 19 var seftFeeTitle //自提费用标题,为方便替换 20 var seftFee //自提费用 21 var size //尺寸 22 var producingArea //产地 23 var material //材质 24 25 /** 26 * 定义统一的字体配置 27 */ 28 var tipFont = "MicrosoftYaHei-Bold" 29 var valueFont = "MicrosoftYaHei" 30 var priceFont = "Century Gothic" 31 32 /** 33 * 定义统一的颜色配置 34 */ 35 //价格的颜色 36 var priceColor = new SolidColor() 37 priceColor.rgb.red = 208 38 priceColor.rgb.green = 28 39 priceColor.rgb.blue = 119 40 //顶部栏的颜色 41 var topBarColor = new SolidColor() 42 topBarColor.rgb.red = 212 43 topBarColor.rgb.green = 0 44 topBarColor.rgb.blue = 102 45 46 /** 47 * 在此读取文件 48 */ 49 //打开logo图片 50 var logoImg = app.open(File("D:/priceCard/liwailogo.jpg")) 51 52 //读取数据文件 53 var dataFile = new File("D:/priceCard/priceCardData.xml") 54 //后续操作设置为“读”操作 55 dataFile.open("r") 56 57 //缓冲变量 58 var xmlCode = dataFile.read() 59 //alert(xmlCode) 60 61 //空文件直接退出 62 if(xmlCode == ""){ 63 alert("文件没有内容") 64 return 65 } 66 67 //新建XML对象 68 var products = new XML(xmlCode) 69 70 //产品总数 71 var productCount = products.product.length() 72 73 //遍历 74 for( i = 0;i < productCount;i++){ 75 76 //变量赋值 77 title = products.product[i].elements()[0] 78 liwaiCode = "里外编码:" + products.product[i].elements()[1] 79 priceTitle = "售价" 80 price = products.product[i].elements()[2] 81 sample = "¥" 82 fiveAssureFeeTitle = "五包费用" 83 fiveAssureFee = "¥" + products.product[i].elements()[3] 84 seftFeeTitle = "自提费用" 85 seftFee = "¥" + products.product[i].elements()[4] 86 size = products.product[i].elements()[5] 87 producingArea = products.product[i].elements()[6] 88 material = products.product[i].elements()[7] 89 90 // 存储当前的单位长度,并设置自定义的单位 91 var originalUnit = preferences.rulerUnits 92 preferences.rulerUnits = Units.PIXELS 93 94 // 声明一个文档 95 var docRef = app.documents.add( 886, 561 ,72.0,"tempDoc") 96 97 // 顶部栏,创建选区并上色 98 // “选区”的填充要在定义组之前操作,否则会报出“fill方法在当前版本不可用” 99 docRef.selection.select([[0,0],[0,20],[886,20],[886,0]],SelectionType.EXTEND) 100 var selRef = docRef.selection 101 selRef.fill( topBarColor, ColorBlendMode.NORMAL, 100, false) 102 103 // 定义一个图片组 104 var layerSetRef =docRef.layerSets.add() 105 layerSetRef.name = "图片组" 106 107 //设置logo所在的文档为活动文档 108 app.activeDocument = logoImg 109 //声明logo图层 110 var logoLayer = logoImg.activeLayer 111 //复制商品图层到背景文档 112 var logoLayerTemp = logoLayer.duplicate(layerSetRef, 113 ElementPlacement.PLACEATEND) 114 //设置背景文档为活动文档 115 app.activeDocument=docRef 116 //logo移动至左下角 117 logoLayerTemp.translate(-265,225) 118 119 //读取当前商品对应的二维码图片 120 var qrCodeImg = app.open(File(products.product[i].elements()[9])) 121 //设置二维码图片所在的文档为活动文档 122 app.activeDocument = qrCodeImg 123 //声明二维码图片图层 124 var qrCodeImgLayer = qrCodeImg.activeLayer 125 //复制二维码图片到背景文档 126 var qrCodeImgLayerTemp = qrCodeImgLayer.duplicate(layerSetRef, 127 ElementPlacement.PLACEATEND) 128 //设置背景文档为活动文档 129 app.activeDocument=docRef 130 //商品图片移动至中间偏右 131 qrCodeImgLayerTemp.translate(320,180) 132 //关闭商品图片文档 133 qrCodeImg.close(SaveOptions.DONOTSAVECHANGES) 134 135 //读取当前价格牌的商品图片 136 var productImg = app.open(File(products.product[i].elements()[8])) 137 //设置商品图片所在的文档为活动文档 138 app.activeDocument = productImg 139 //声明商品图片图层 140 var productImgLayer = productImg.activeLayer 141 //复制商品图层到背景文档 142 var productImgLayerTemp = productImgLayer.duplicate(layerSetRef, 143 ElementPlacement.PLACEATEND) 144 //设置背景文档为活动文档 145 app.activeDocument=docRef 146 //商品图片移动至中间偏右 147 productImgLayerTemp.translate(200,-50) 148 //关闭商品图片文档 149 productImg.close(SaveOptions.DONOTSAVECHANGES) 150 151 /** 152 *内容开始 153 */ 154 // 商品名称 155 var proNameLayerRef = docRef.artLayers.add() 156 proNameLayerRef.kind = LayerKind.TEXT 157 var proNameTextItemRef = proNameLayerRef.textItem 158 proNameTextItemRef.contents = title 159 proNameTextItemRef.position = Array(55, 70) 160 proNameTextItemRef.font = tipFont 161 proNameTextItemRef.size = 30 162 163 //里外编码 164 var liwaiCodeLayerRef = docRef.artLayers.add() 165 liwaiCodeLayerRef.kind = LayerKind.TEXT 166 var liwaiCodeTextItemRef = liwaiCodeLayerRef.textItem 167 liwaiCodeTextItemRef.contents = liwaiCode 168 liwaiCodeTextItemRef.position = Array(55, 95) 169 liwaiCodeTextItemRef.font = valueFont 170 liwaiCodeTextItemRef.size = 14 171 172 //售价标题 173 var liwaiCodeLayerRef = docRef.artLayers.add() 174 liwaiCodeLayerRef.kind = LayerKind.TEXT 175 var liwaiCodeTextItemRef = liwaiCodeLayerRef.textItem 176 liwaiCodeTextItemRef.contents = priceTitle 177 liwaiCodeTextItemRef.position = Array(55, 135) 178 liwaiCodeTextItemRef.font = tipFont 179 liwaiCodeTextItemRef.size = 22 180 181 //¥ 182 var sampleLayerRef = docRef.artLayers.add() 183 sampleLayerRef.kind = LayerKind.TEXT 184 var sampleTextItemRef = sampleLayerRef.textItem 185 sampleTextItemRef.contents = sample 186 sampleTextItemRef.position = Array(50, 235) 187 sampleTextItemRef.font = tipFont 188 sampleTextItemRef.size = 40 189 sampleTextItemRef.color = priceColor 190 191 //金额 192 var liwaiPriceLayerRef = docRef.artLayers.add() 193 liwaiPriceLayerRef.kind = LayerKind.TEXT 194 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 195 liwaiPriceTextItemRef.contents = price 196 liwaiPriceTextItemRef.position = Array(105, 235) 197 liwaiPriceTextItemRef.font = valueFont 198 liwaiPriceTextItemRef.size = 100 199 liwaiPriceTextItemRef.color = priceColor 200 201 //五包费用 202 var liwaiPriceLayerRef = docRef.artLayers.add() 203 liwaiPriceLayerRef.kind = LayerKind.TEXT 204 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 205 liwaiPriceTextItemRef.contents = fiveAssureFeeTitle 206 liwaiPriceTextItemRef.position = Array(55, 275) 207 liwaiPriceTextItemRef.font = tipFont 208 liwaiPriceTextItemRef.size = 20 209 210 //五包费用金额 211 var liwaiPriceLayerRef = docRef.artLayers.add() 212 liwaiPriceLayerRef.kind = LayerKind.TEXT 213 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 214 liwaiPriceTextItemRef.contents = fiveAssureFee 215 liwaiPriceTextItemRef.position = Array(140, 275) 216 liwaiPriceTextItemRef.font = valueFont 217 liwaiPriceTextItemRef.size = 18 218 liwaiPriceTextItemRef.color = priceColor 219 220 //自提费用 221 var liwaiPriceLayerRef = docRef.artLayers.add() 222 liwaiPriceLayerRef.kind = LayerKind.TEXT 223 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 224 liwaiPriceTextItemRef.contents = seftFeeTitle 225 liwaiPriceTextItemRef.position = Array(250, 275) 226 liwaiPriceTextItemRef.font = tipFont 227 liwaiPriceTextItemRef.size = 20 228 229 //自提费用金额 230 var liwaiPriceLayerRef = docRef.artLayers.add() 231 liwaiPriceLayerRef.kind = LayerKind.TEXT 232 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 233 liwaiPriceTextItemRef.contents = seftFee 234 liwaiPriceTextItemRef.position = Array(335, 275) 235 liwaiPriceTextItemRef.font = valueFont 236 liwaiPriceTextItemRef.size = 18 237 liwaiPriceTextItemRef.color = priceColor 238 239 //规格 240 var liwaiPriceLayerRef = docRef.artLayers.add() 241 liwaiPriceLayerRef.kind = LayerKind.TEXT 242 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 243 liwaiPriceTextItemRef.contents = "规格:" 244 liwaiPriceTextItemRef.position = Array(55, 345) 245 liwaiPriceTextItemRef.font = tipFont 246 liwaiPriceTextItemRef.size = 20 247 248 //规格数值 249 var liwaiPriceLayerRef = docRef.artLayers.add() 250 liwaiPriceLayerRef.kind = LayerKind.TEXT 251 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 252 liwaiPriceTextItemRef.contents = size 253 liwaiPriceTextItemRef.position = Array(125, 345) 254 liwaiPriceTextItemRef.font = valueFont 255 liwaiPriceTextItemRef.size = 20 256 257 //产地 258 var liwaiPriceLayerRef = docRef.artLayers.add() 259 liwaiPriceLayerRef.kind = LayerKind.TEXT 260 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 261 liwaiPriceTextItemRef.contents = "产地:" 262 liwaiPriceTextItemRef.position = Array(55, 375) 263 liwaiPriceTextItemRef.font = tipFont 264 liwaiPriceTextItemRef.size = 20 265 266 //产地值 267 var liwaiPriceLayerRef = docRef.artLayers.add() 268 liwaiPriceLayerRef.kind = LayerKind.TEXT 269 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 270 liwaiPriceTextItemRef.contents = producingArea 271 liwaiPriceTextItemRef.position = Array(125, 375) 272 liwaiPriceTextItemRef.font = valueFont 273 liwaiPriceTextItemRef.size = 20 274 275 //材质 276 var liwaiPriceLayerRef = docRef.artLayers.add() 277 liwaiPriceLayerRef.kind = LayerKind.TEXT 278 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 279 liwaiPriceTextItemRef.contents = "材质:" 280 liwaiPriceTextItemRef.position = Array(55, 405) 281 liwaiPriceTextItemRef.font = tipFont 282 liwaiPriceTextItemRef.size = 20 283 284 //材质值 285 var liwaiPriceLayerRef = docRef.artLayers.add() 286 liwaiPriceLayerRef.kind = LayerKind.TEXT 287 liwaiPriceLayerRef.textItem.kind = TextType.PARAGRAPHTEXT 288 var liwaiPriceTextItemRef = liwaiPriceLayerRef.textItem 289 liwaiPriceTextItemRef.contents = material 290 liwaiPriceTextItemRef.position = Array(125, 391) 291 liwaiPriceTextItemRef.font = valueFont 292 liwaiPriceTextItemRef.width = 550 293 liwaiPriceTextItemRef.height = 200 294 liwaiPriceTextItemRef.size = 20 295 296 //保存文件 297 new Folder("D:/priceCard/result").create () 298 jpgFile = new File( "D:/priceCard/result/" + products.product[i].elements()[1] + ".jpeg" ) 299 jpgSaveOptions = new JPEGSaveOptions() 300 jpgSaveOptions.embedColorProfile = true 301 jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE 302 jpgSaveOptions.matte = MatteType.NONE 303 jpgSaveOptions.quality = 12 304 app.activeDocument.saveAs(jpgFile, jpgSaveOptions, true, 305 Extension.LOWERCASE) 306 307 //强制关闭 308 docRef.close(SaveOptions.DONOTSAVECHANGES) 309 310 //恢复默认长度单位 311 app.preferences.rulerUnits = originalUnit 312 } 313 //关闭logo所在的文档 314 logoImg.close(SaveOptions.DONOTSAVECHANGES) 315 alert("生成" + productCount + "条产品信息,请在以下位置\"D:/priceCard/result/\"查看") 316 }
代码里的priceCardData.xml的文档格式是下面这个样子的
<products> <product> <!--模板文件禁止修改--> <产品名称></产品名称> <!--里外编码--> <里外编码></里外编码> <!--售价--> <售价></售价> <!--五包费用--> <五包费用></五包费用> <!--自提费用--> <自提费用></自提费用> <!--规格大小--> <规格大小></规格大小> <!--产地--> <产地></产地> <!--材质--> <材质></材质> <!--产品图片地址--> <产品图片地址></产品图片地址> <!--产品二维码地址--> <产品二维码地址></产品二维码地址> </product> <product> <!--模板文件禁止修改--> <产品名称></产品名称> <!--里外编码--> <里外编码></里外编码> <!--售价--> <售价></售价> <!--五包费用--> <五包费用></五包费用> <!--自提费用--> <自提费用></自提费用> <!--规格大小--> <规格大小></规格大小> <!--产地--> <产地></产地> <!--材质--> <材质></材质> <!--产品图片地址--> <产品图片地址></产品图片地址> <!--产品二维码地址--> <产品二维码地址></产品二维码地址> </product> </products>
看完了这个文档格式,你应该会有以下的疑问:
1:博主逗比吧,XML标签怎么用中文?!
2:写两遍product节点干什么?手抖么?
哎,我知道自己挺逗的,但是这事要从开发之初说起,我最开始不是用XML来存放数据的,我本来幻想着可以使用CVS文件,或者PRN文件来存放数据源,然而都是以失败告终,因为商品的描述里什么都有可能存,一些卖萌的编辑什么都会写的。。。都怪我太年轻,用什么分割数据搞不清啊。。。
好了,回到问题1,我为什么用中文?因为,是为了避免装13,和让非技术人员看懂。为什么这么说呢,因为用Excel打开这个模板文件,Excel会把子节点当字段名来显示,就比如
<产品二维码地址></产品二维码地址>
这个节点在Excel里的标题就是“产品二维码地址”,这就是用中文的原因,方便理解。不过呢,这里提一个有趣的现象,使用中文去取节点里的内容竟然是可以的,很是让我惊喜哎
代码里可以看到,我是通过
title = products.product[i].elements()[0]
去取商品名称的值的,但是实际上
title = products.product[i].产品名称
也能取得商品名称的值,感觉帅帅哒!
不过呢,我怕出问题,还是没有用中文去取。。。
再看问题2,为什么写两遍,这个就要问Excel了,因为只写一个子节点的话,Excel里是没有表头的, 写两个才有带表头的表格,如下
产品名称 | 里外编码 | 售价 | 五包费用 | 自提费用 | 规格大小 | 产地 | 材质 | 产品图片地址 | 产品二维码地址 |
好了,使用Excel填写产品信息,再保存为XMl数据文件,准备工作就算完成了,接下来就是见证奇迹的时刻了
怎么运行?在页面里运行?看着不像啊。。app是个啥?浏览器认识么。。
其实是在photoShop里运行的,将写好的脚本放置于Adobe Photoshop CS5\Presets\Scripts下,打开PS,已经打开的就重启一下PS,之后你会在PS->文件->脚本下发现放入的脚本文件,默认是支持.jsx结尾的脚本文件,记得文档里说.js结尾的文件也支持来着。点击运行之后,你就会发现,图层啊,文字啊,刷刷的生成,刷刷的关闭,自动化的感觉很好啊,代码中的图片生成速度是10s左右一张,最高画质的,还可以接受。
好了,洋洋洒洒写了这么多,一是为了记录一下自己的心得,二是希望能给那些深陷在重复性设计工作中的人们一些帮助,只要稍微懂得一些脚本知识,能看懂英文文档就可以写啦,很炫酷的。PS脚本对我来说是一个新鲜的东西,或许我写的这些小玩意早就有大神在我之前写过,而且效率更高,或许有现成的软件可以直接生成,或许我做了很多无用功,但是都没关系啦,因为有时候是不是坑,你只有跳进去再爬出来才能知道它是不是,这样以后才好绕着走。博文至此,希望技术大神,和设计大师不用过分重视,毕竟这篇小小的博文只能是一个针对初学者的小例子,就比如说我,我作为一个程序员,两天前都不知道PS可以运行脚本,而对于那些和我一样的小伙伴们,如果你们感兴趣,自己可以先去写个脚本,alert一下自己的helloworld!哈哈~
开博第二篇:记一个利用JavaScript,编写PS脚本,开发图片量产工具
标签:style blog color java os 使用 io 文件 for
原文地址:http://www.cnblogs.com/1-1-0/p/3932999.html