Export PSDUI.jsx 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142
  1. // **************************************************
  2. // This file created by Brett Bibby (c) 2010-2013
  3. // You may freely use and modify this file as you see fit
  4. // You may not sell it
  5. //**************************************************
  6. // hidden object game exporter
  7. //$.writeln("=== Starting Debugging Session ===");
  8. // enable double clicking from the Macintosh Finder or the Windows Explorer
  9. #target photoshop
  10. // debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning)
  11. // $.level = 0;
  12. // debugger; // launch debugger on next line
  13. var sceneData;
  14. var sourcePsd;
  15. var duppedPsd;
  16. var destinationFolder;
  17. var uuid;
  18. var sourcePsdName;
  19. var slicePaddingArr = new Array(0,0,0,0)
  20. var sliceOriArr = new Array(0,0,0,0)
  21. main();
  22. function main(){
  23. // got a valid document?
  24. if (app.documents.length <= 0)
  25. {
  26. if (app.playbackDisplayDialogs != DialogModes.NO)
  27. {
  28. alert("You must have a document open to export!");
  29. }
  30. // quit, returning 'cancel' makes the actions palette not record our script
  31. return 'cancel';
  32. }
  33. // ask for where the exported files should go
  34. destinationFolder = Folder.selectDialog("Choose the destination for export.");
  35. if (!destinationFolder)
  36. {
  37. return;
  38. }
  39. // cache useful variables
  40. uuid = 1;
  41. sourcePsdName = app.activeDocument.name;
  42. var layerCount = app.documents[sourcePsdName].layers.length;
  43. var layerSetsCount = app.documents[sourcePsdName].layerSets.length;
  44. if ((layerCount <= 1) && (layerSetsCount <= 0))
  45. {
  46. if (app.playbackDisplayDialogs != DialogModes.NO)
  47. {
  48. alert("You need a document with multiple layers to export!");
  49. // quit, returning 'cancel' makes the actions palette not record our script
  50. return 'cancel';
  51. }
  52. }
  53. // setup the units in case it isn't pixels
  54. var savedRulerUnits = app.preferences.rulerUnits;
  55. var savedTypeUnits = app.preferences.typeUnits;
  56. app.preferences.rulerUnits = Units.PIXELS;
  57. app.preferences.typeUnits = TypeUnits.PIXELS;
  58. // duplicate document so we can extract everythng we need
  59. duppedPsd = app.activeDocument.duplicate();
  60. duppedPsd.activeLayer = duppedPsd.layers[duppedPsd.layers.length - 1];
  61. hideAllLayers(duppedPsd);
  62. // export layers
  63. sceneData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
  64. sceneData += "<PSDUI>";
  65. sceneData += "\n<psdSize>";
  66. sceneData += "<width>" + duppedPsd.width.value + "</width>";
  67. sceneData += "<height>" + duppedPsd.height.value+ "</height>";
  68. sceneData += "</psdSize>";
  69. sceneData += "\n<layers>";
  70. exportAllLayers(duppedPsd);
  71. sceneData += "</layers>";
  72. sceneData += "\n</PSDUI>";
  73. $.writeln(sceneData);
  74. duppedPsd.close(SaveOptions.DONOTSAVECHANGES);
  75. // create export
  76. var sceneFile = new File(destinationFolder + "/" + destinationFolder.name + ".xml");
  77. sceneFile.encoding = "utf-8"; //写文件时指定编码,不然中文会出现乱码
  78. sceneFile.open('w');
  79. sceneFile.writeln(sceneData);
  80. sceneFile.close();
  81. app.preferences.rulerUnits = savedRulerUnits;
  82. app.preferences.typeUnits = savedTypeUnits;
  83. }
  84. function exportAllLayers(obj)
  85. {
  86. if (typeof(obj) == "undefined"){
  87. return;
  88. }
  89. if (typeof(obj.layers) != "undefined" && obj.layers.length>0) {
  90. for (var i = obj.layers.length - 1; 0 <= i; i--)
  91. {
  92. exportLayer(obj.layers[i])
  93. }
  94. }
  95. else{
  96. exportLayer(obj)
  97. };
  98. }
  99. function exportLayer(obj)
  100. {
  101. if (typeof(obj) == "undefined"){
  102. return;
  103. }
  104. if (obj.typename == "LayerSet") {
  105. exportLayerSet(obj);
  106. }
  107. else if (obj.typename = "ArtLayer"){
  108. exportArtLayer(obj);
  109. }
  110. }
  111. function exportLayerSet(_layer)
  112. {
  113. if (typeof(_layer.layers) == "undefined" || _layer.layers.length<=0 ){
  114. return
  115. }
  116. if (_layer.name.search("@ScrollView") >= 0)
  117. {
  118. exportScrollView(_layer);
  119. }
  120. else if (_layer.name.search("@Grid") >= 0)
  121. {
  122. exportGrid(_layer);
  123. }
  124. else if (_layer.name.search("@Button") >= 0)
  125. {
  126. exportButton(_layer);
  127. }
  128. else if (_layer.name.search("@Toggle") >= 0)
  129. {
  130. exportToggle(_layer);
  131. }
  132. else if (_layer.name.search("@Panel") >= 0)
  133. {
  134. exportPanel(_layer);
  135. }
  136. else if (_layer.name.search("@Slider")>=0) {
  137. exportSlider(_layer);
  138. }
  139. else if (_layer.name.search("@Group")>=0) {
  140. exportGroup(_layer);
  141. }
  142. else if (_layer.name.search("@InputField") >=0) {
  143. exportInputField(_layer);
  144. }
  145. else if (_layer.name.search("@Scrollbar") >=0) {
  146. exportScrollBar(_layer);
  147. }else if (_layer.name.search("@LE") >=0) {//增加布局元素导出
  148. exportLayoutElement(_layer);
  149. }
  150. else
  151. {
  152. sceneData += "<Layer>";
  153. sceneData += "<type>Normal</type>";
  154. sceneData += "<name>" + _layer.name + "</name>";
  155. sceneData += "<layers>";
  156. exportAllLayers(_layer)
  157. sceneData += "</layers>";
  158. sceneData += "</Layer>";
  159. }
  160. }
  161. function exportLayoutElement(obj)
  162. {
  163. sceneData += "<Layer>";
  164. sceneData += "<type>LayoutElement</type>";
  165. var itemName = obj.name.substring(0, obj.name.search("@"));
  166. sceneData += "<name>" + itemName + "</name>";
  167. sceneData += "<layers>";
  168. exportAllLayers(obj);
  169. // sceneData += "<images>";
  170. // for (var j = obj.artLayers.length - 1; 0 <= j; j--)
  171. // {
  172. // exportArtLayer(obj.artLayers[j]);
  173. // }
  174. // sceneData += "</images>";
  175. sceneData += "</layers>";
  176. obj.visible = true;
  177. showAllLayers(obj);
  178. var recSize = getLayerRec(duppedPsd.duplicate());
  179. sceneData += "<position>";
  180. sceneData += "<x>" + recSize.x + "</x>";
  181. sceneData += "<y>" + recSize.y + "</y>";
  182. sceneData += "</position>";
  183. sceneData += "<size>";
  184. sceneData += "<width>" + recSize.width + "</width>";
  185. sceneData += "<height>" + recSize.height + "</height>";
  186. sceneData += "</size>";
  187. hideAllLayers(obj);
  188. sceneData += "</Layer>";
  189. }
  190. function exportScrollView(obj)
  191. {
  192. var itemName = obj.name.substring(0, obj.name.search("@"));
  193. sceneData += ("<Layer>\n<type>ScrollView</type>\n<name>" + itemName + "</name>\n");
  194. sceneData += ("<layers>\n");
  195. exportAllLayers(obj);
  196. sceneData += ("</layers>");
  197. var params = obj.name.split(":");
  198. if (params.length > 2)
  199. {
  200. alert(obj.name + "-------Layer's name is illegal------------");
  201. }
  202. var recSize;
  203. if (obj.layers[obj.layers.length - 1].name.search("@Size") < 0)
  204. {
  205. alert("Bottom layer's name doesn't contain '@Size'");
  206. }
  207. else
  208. {
  209. obj.layers[obj.layers.length - 1].visible = true;
  210. recSize = getLayerRec(duppedPsd.duplicate());
  211. sceneData += "<position>";
  212. sceneData += "<x>" + recSize.x + "</x>";
  213. sceneData += "<y>" + recSize.y + "</y>";
  214. sceneData += "</position>";
  215. sceneData += "<size>";
  216. sceneData += "<width>" + recSize.width + "</width>";
  217. sceneData += "<height>" + recSize.height + "</height>";
  218. sceneData += "</size>";
  219. obj.layers[obj.layers.length - 1].visible = false;
  220. }
  221. //以下计算padding和spacing
  222. obj.layers[0].visible = true;
  223. showAllLayers(obj.layers[0]); //子图层组已经在上面导出过,要再次计算size需先将其显示
  224. var rec0 = getLayerRec(duppedPsd.duplicate());
  225. hideAllLayers(obj.layers[0]);
  226. obj.layers[0].visible = false;
  227. obj.layers[1].visible = true;
  228. showAllLayers(obj.layers[1]);
  229. var rec1 = getLayerRec(duppedPsd.duplicate());
  230. hideAllLayers(obj.layers[0]);
  231. obj.layers[1].visible = false;
  232. var spacing;
  233. var paddingx;
  234. var paddingy;
  235. if(params[1].search("H") >= 0) //水平间距
  236. {
  237. spacing = rec1.x - rec0.x - rec0.width;
  238. paddingx = rec0.x - (recSize.x - recSize.width / 2) - rec0.width / 2; //x方向边距,默认左右相等
  239. paddingy = (recSize.height - rec0.height) / 2 ; //暂时只考虑上下边距相等
  240. //paddingy = recSize.height / 2 - rec0.height / 2 - (rec0.y - recSize.y); //上边距
  241. //paddingy2 = recSize.height - rec0.height - paddingy; //下边距
  242. }
  243. else //垂直间距
  244. {
  245. spacing = rec0.y - rec1.y - rec0.height;
  246. paddingx = (recSize.width - rec0.width) / 2 ;
  247. paddingy = (recSize.y + recSize.height / 2) - rec0.y - rec0.height / 2;
  248. }
  249. sceneData += "<arguments>";
  250. sceneData += "<string>" + params[1] + "</string>"; //滑动方向
  251. sceneData += "<string>" + spacing + "</string>";
  252. sceneData += "<string>" + Math.floor (paddingx) + "</string>";
  253. sceneData += "<string>" + Math.floor (paddingy) + "</string>";
  254. sceneData += "</arguments>";
  255. sceneData += "</Layer>";
  256. }
  257. function setLayerSizeAndPos(layer)
  258. {
  259. layer.visible = true;
  260. var recSize = getLayerRec(duppedPsd.duplicate());
  261. sceneData += "<position>";
  262. sceneData += "<x>" + recSize.x + "</x>";
  263. sceneData += "<y>" + recSize.y + "</y>";
  264. sceneData += "</position>";
  265. sceneData += "<size>";
  266. sceneData += "<width>" + recSize.width + "</width>";
  267. sceneData += "<height>" + recSize.height + "</height>";
  268. sceneData += "</size>";
  269. layer.visible = false;
  270. }
  271. function exportGrid(obj)
  272. {
  273. var itemName = obj.name.substring(0, obj.name.search("@"));
  274. sceneData += ("<Layer>\n<type>Grid</type>\n<name>" + itemName + "</name>\n");
  275. sceneData += ("<layers>\n");
  276. exportAllLayers(obj);
  277. sceneData += ("</layers>");
  278. var params = obj.name.split(":");
  279. if (params.length != 3)
  280. {
  281. alert("Layer's name is illegal");
  282. }
  283. var recSize;
  284. if (obj.layers[obj.layers.length - 1].name.search("@Size") < 0)
  285. {
  286. alert("Bottom layer's name doesn't contain '@Size'");
  287. }
  288. else
  289. {
  290. setLayerSizeAndPos(obj.layers[obj.layers.length - 1]);
  291. }
  292. var totalContentCount = obj.layers.length - 1;
  293. obj.layers[0].visible = true;
  294. showAllLayers(obj.layers[0]); //子图层组已经在上面导出过,要再次计算size需先将其显示
  295. var rec0 = getLayerRec(duppedPsd.duplicate());
  296. hideAllLayers(obj.layers[0]);
  297. obj.layers[0].visible = false;
  298. var renderHorizontalGap = params[2] > 1 ? (recSize.width - rec0.width * params[2])/(params[2] - 1) : 0;
  299. var renderVerticalGap = params[1] > 1 ? (recSize.height - rec0.height * params[1])/(params[1] - 1) : 0;
  300. sceneData += "<arguments>";
  301. sceneData += "<string>" + params[1] + "</string>"; //行数
  302. sceneData += "<string>" + params[2] + "</string>"; //列数
  303. sceneData += "<string>" + rec0.width + "</string>"; //render width
  304. sceneData += "<string>" + rec0.height + "</string>"; //render height
  305. sceneData += "<string>" + Math.floor(renderHorizontalGap) + "</string>"; //水平间距
  306. sceneData += "<string>" + Math.floor(renderVerticalGap) + "</string>"; //垂直间距
  307. sceneData += "</arguments>";
  308. sceneData += "</Layer>";
  309. }
  310. function exportGroup(obj)
  311. {
  312. var itemName = obj.name.substring(0, obj.name.search("@"));
  313. sceneData += ("<Layer>\n<type>Group</type>\n<name>" + itemName + "</name>\n");
  314. exportAllLayers(obj);
  315. var params = obj.name.split(":");
  316. if (params.length != 3 )
  317. {
  318. alert(obj.name + "-------Layer's name not equals 2------------");
  319. }
  320. var recSize;
  321. if (obj.layers[obj.layers.length - 1].name.search("@Size") < 0)
  322. {
  323. alert("Bottom layer's name doesn't contain '@Size'");
  324. }
  325. else
  326. {
  327. obj.layers[obj.layers.length - 1].visible = true;
  328. recSize = getLayerRec(duppedPsd.duplicate());
  329. sceneData += "<position>";
  330. sceneData += "<x>" + recSize.x + "</x>";
  331. sceneData += "<y>" + recSize.y + "</y>";
  332. sceneData += "</position>";
  333. sceneData += "<size>";
  334. sceneData += "<width>" + recSize.width + "</width>";
  335. sceneData += "<height>" + recSize.height + "</height>";
  336. sceneData += "</size>";
  337. obj.layers[obj.layers.length - 1].visible = false;
  338. }
  339. sceneData += "<arguments>";
  340. sceneData += "<string>" + params[1] + "</string>"; //方向
  341. sceneData += "<string>" + params[2] + "</string>"; //span
  342. sceneData += "</arguments>";
  343. sceneData += "</Layer>";
  344. }
  345. function exportInputField(obj)
  346. {
  347. var itemName = obj.name.substring(0, obj.name.search("@"));
  348. sceneData += ("<Layer>\n<type>InputField</type>\n<name>" + itemName + "</name>\n");
  349. sceneData += "<layers>";
  350. // sceneData += "<images>\n";
  351. for (var i = obj.layers.length - 1; 0 <= i; i--)
  352. {
  353. exportArtLayer(obj.layers[i]);
  354. }
  355. sceneData += "</layers>";
  356. // sceneData += "\n</images>\n</Layer>";
  357. sceneData += "\n</Layer>";
  358. }
  359. function exportButton(obj)
  360. {
  361. var itemName = obj.name.substring(0, obj.name.search("@"));
  362. sceneData += ("<Layer>\n<type>Button</type>\n<name>" + itemName + "</name>\n");
  363. sceneData += "<layers>";
  364. // sceneData += "<images>\n";
  365. for (var i = obj.layers.length - 1; 0 <= i; i--)
  366. {
  367. exportArtLayer(obj.layers[i]);
  368. }
  369. sceneData += "</layers>";
  370. // sceneData += "\n</images>\n</Layer>";
  371. sceneData += "\n</Layer>";
  372. }
  373. function exportToggle(obj)
  374. {
  375. var itemName = obj.name.substring(0, obj.name.search("@"));
  376. sceneData += ("<Layer>\n<type>Toggle</type>\n<name>" + itemName + "</name>\n");
  377. sceneData += "<layers>";
  378. // sceneData += "<images>\n";
  379. for (var i = obj.layers.length - 1; 0 <= i; i--)
  380. {
  381. exportArtLayer(obj.layers[i]);
  382. }
  383. sceneData += "</layers>";
  384. // sceneData += "\n</images>\n</Layer>";
  385. sceneData += "\n</Layer>";
  386. }
  387. function exportSlider(obj)
  388. {
  389. var itemName = obj.name.substring(0, obj.name.search("@"));
  390. sceneData += ("<Layer>\n<type>Slider</type>\n<name>" + itemName + "</name>\n");
  391. var params = obj.name.split(":");
  392. if (params.length != 2)
  393. {
  394. alert(obj.name + "-------Layer's name is not 1 argument------------");
  395. }
  396. var recSize;
  397. if (obj.layers[obj.layers.length - 1].name.search("@Size") < 0)
  398. {
  399. alert("Bottom layer's name doesn't contain '@Size'");
  400. }
  401. else
  402. {
  403. setLayerSizeAndPos(obj.layers[obj.layers.length - 1]);
  404. }
  405. sceneData += "<arguments>";
  406. sceneData += "<string>" + params[1] + "</string>"; //滑动方向
  407. sceneData += "</arguments>";
  408. // sceneData += "<images>\n";
  409. sceneData += "<layers>";
  410. for (var i = obj.layers.length - 1; 0 <= i; i--)
  411. {
  412. exportArtLayer(obj.layers[i]);
  413. }
  414. sceneData += "</layers>";
  415. // sceneData += "\n</images>\n</Layer>";
  416. sceneData += "\n</Layer>";
  417. }
  418. function exportScrollBar(obj)
  419. {
  420. var itemName = obj.name.substring(0, obj.name.search("@"));
  421. sceneData += ("<Layer>\n<type>ScrollBar</type>\n<name>" + itemName + "</name>\n");
  422. var params = obj.name.split(":");
  423. if (params.length != 3)
  424. {
  425. alert(obj.name + "-------Layer's name is not 1 argument------------");
  426. }
  427. sceneData += "<arguments>";
  428. sceneData += "<string>" + params[1] + "</string>"; //滑动方向
  429. sceneData += "<string>" + params[2] + "</string>"; //比例
  430. sceneData += "</arguments>";
  431. // sceneData += "<images>\n";
  432. sceneData += "<layers>";
  433. for (var i = obj.layers.length - 1; 0 <= i; i--)
  434. {
  435. exportArtLayer(obj.layers[i]);
  436. }
  437. sceneData += "</layers>";
  438. // sceneData += "\n</images>\n</Layer>";
  439. sceneData += "\n</Layer>";
  440. }
  441. function exportPanel(obj)
  442. {
  443. var itemName = obj.name.substring(0, obj.name.search("@"));
  444. sceneData += ("<Layer>\n<type>Panel</type>\n<name>" + itemName + "</name>\n");
  445. exportAllLayers(obj);
  446. // sceneData += "<images>\n";
  447. sceneData += "<layers>";
  448. for (var j = obj.artLayers.length - 1; 0 <= j; j--)
  449. {
  450. exportArtLayer(obj.artLayers[j]);
  451. }
  452. sceneData += "</layers>";
  453. // sceneData += "\n</images>\n</Layer>";
  454. sceneData += "\n</Layer>";
  455. }
  456. function exportArtLayer(obj)
  457. {
  458. if (typeof(obj) == "undefined") {return};
  459. if (obj.name.search("@Size") >= 0) {return};
  460. sceneData += "\n<Layer>";
  461. sceneData += "<type>Normal</type>";
  462. //sceneData += "<name>" + makeValidFileName(obj.name) + "</name>";
  463. var validFileName = makeValidFileName(obj.name);
  464. sceneData += "<name>" + validFileName + "</name>";
  465. sceneData += "<image>\n";
  466. // sceneData += "<PSImage>\n";
  467. if (LayerKind.TEXT == obj.kind)
  468. {
  469. exportLabel(obj,validFileName);
  470. }
  471. else if (obj.name.search("Texture") >= 0)
  472. {
  473. exportTexture(obj,validFileName);
  474. }
  475. else
  476. {
  477. exportImage(obj,validFileName);
  478. }
  479. sceneData += "</image>";
  480. // sceneData += "</PSImage>";
  481. sceneData += "\n</Layer>";
  482. }
  483. function exportLabel(obj,validFileName)
  484. {
  485. //有些文本如标题,按钮,美术用的是其他字体,可能还加了各种样式,需要当做图片切出来使用
  486. if(obj.name.search("_ArtStatic") >= 0)
  487. {
  488. exportImage(obj,validFileName);
  489. return;
  490. }
  491. //处理静态文本,会对应unity的静态字体
  492. var StaticText = false;
  493. if(obj.name.search("_Static") >= 0)
  494. {
  495. StaticText = true;
  496. }
  497. sceneData += "<imageType>" + "Label" + "</imageType>\n";
  498. //var validFileName = makeValidFileName(obj.name);
  499. sceneData += "<name>" + validFileName + "</name>\n";
  500. obj.visible = true;
  501. saveScenePng(duppedPsd.duplicate(), validFileName, false);
  502. obj.visible = false;
  503. sceneData += "<arguments>";
  504. sceneData += "<string>" + obj.textItem.color.rgb.hexValue + "</string>";
  505. if(StaticText == true)
  506. {
  507. sceneData += "<string>" + obj.textItem.font + "_Static" + "</string>";
  508. }
  509. else
  510. {
  511. sceneData += "<string>" + obj.textItem.font + "</string>";
  512. }
  513. //sceneData += "<string>" + obj.textItem.font + "</string>";
  514. sceneData += "<string>" + obj.textItem.size.value + "</string>";
  515. sceneData += "<string>" + obj.textItem.contents + "</string>";
  516. //段落文本带文本框,可以取得对齐方式
  517. if(obj.textItem.kind == TextType.PARAGRAPHTEXT)
  518. {
  519. sceneData += "<string>" + obj.textItem.justification + "</string>"; //加对齐方式
  520. }
  521. sceneData += "</arguments>";
  522. }
  523. function exportTexture(obj,validFileName)
  524. {
  525. //var validFileName = makeValidFileName(obj.name);
  526. sceneData += "<imageType>" + "Texture" + "</imageType>\n";
  527. sceneData += "<name>" + validFileName + "</name>\n";
  528. obj.visible = true;
  529. saveScenePng(duppedPsd.duplicate(), validFileName, true);
  530. obj.visible = false;
  531. }
  532. function exportImage(obj,validFileName)
  533. {
  534. //var validFileName = makeValidFileName(obj.name);
  535. var oriName = obj.name
  536. sceneData += "<name>" + validFileName + "</name>\n";
  537. if (obj.name.search("Common") >= 0)
  538. {
  539. sceneData += "<imageSource>" + "Common" + "</imageSource>\n";
  540. }
  541. else if(obj.name.search("Global") >= 0)
  542. {
  543. sceneData += "<imageSource>" + "Global" + "</imageSource>\n";
  544. }
  545. else
  546. {
  547. sceneData += "<imageSource>" + "Custom" + "</imageSource>\n";
  548. }
  549. if (oriName.search("_9S") >= 0)
  550. {
  551. sceneData += "<imageType>" + "SliceImage" + "</imageType>\n";
  552. obj.visible = true;
  553. var _objName = obj.name
  554. // var newDoc = app.documents.add(duppedPsd.width, duppedPsd.height,duppedPsd.resolution, _objName+"doc",NewDocumentMode.RGB,DocumentFill.TRANSPARENT)
  555. // app.activeDocument = duppedPsd
  556. // obj.copy()
  557. // app.activeDocument = newDoc
  558. // newDoc.paste()
  559. // newDoc.activeLayer.name = _objName
  560. var recSize = getLayerRec(duppedPsd.duplicate(),true);
  561. sceneData += "<position>";
  562. sceneData += "<x>" + recSize.x + "</x>";
  563. sceneData += "<y>" + recSize.y + "</y>";
  564. sceneData += "</position>";
  565. sceneData += "<size>";
  566. sceneData += "<width>" + recSize.width + "</width>";
  567. sceneData += "<height>" + recSize.height + "</height>";
  568. sceneData += "</size>";
  569. // _9sliceCutImg(newDoc,_objName,validFileName);
  570. _9sliceCutImg(duppedPsd.duplicate(),_objName,validFileName);
  571. obj.visible = false;
  572. return;
  573. }
  574. else if(oriName.search("LeftHalf") > 0) //左右对称的图片切左边一半
  575. {
  576. sceneData += "<imageType>" + "LeftHalfImage" + "</imageType>\n";
  577. obj.visible = true;
  578. var recSize = getLayerRec(duppedPsd.duplicate());
  579. sceneData += "<position>";
  580. sceneData += "<x>" + recSize.x + "</x>";
  581. sceneData += "<y>" + recSize.y + "</y>";
  582. sceneData += "</position>";
  583. sceneData += "<size>";
  584. sceneData += "<width>" + recSize.width + "</width>";
  585. sceneData += "<height>" + recSize.height + "</height>";
  586. sceneData += "</size>";
  587. cutLeftHalf(duppedPsd.duplicate(),validFileName);
  588. obj.visible = false;
  589. return;
  590. }
  591. else if(obj.name.search("BottomHalf") > 0) //上下对称的图片切底部一半
  592. {
  593. sceneData += "<imageType>" + "BottomHalfImage" + "</imageType>\n";
  594. obj.visible = true;
  595. //半图要先计算出大小和位置
  596. var recSize = getLayerRec(duppedPsd.duplicate());
  597. sceneData += "<position>";
  598. sceneData += "<x>" + recSize.x + "</x>";
  599. sceneData += "<y>" + recSize.y + "</y>";
  600. sceneData += "</position>";
  601. sceneData += "<size>";
  602. sceneData += "<width>" + recSize.width + "</width>";
  603. sceneData += "<height>" + recSize.height + "</height>";
  604. sceneData += "</size>";
  605. cutBottomHalf(duppedPsd.duplicate(),validFileName);
  606. obj.visible = false;
  607. return;
  608. }
  609. else if(obj.name.search("Quarter") > 0) //上下左右均对称的图片切左下四分之一
  610. {
  611. sceneData += "<imageType>" + "QuarterImage" + "</imageType>\n";
  612. obj.visible = true;
  613. var recSize = getLayerRec(duppedPsd.duplicate());
  614. sceneData += "<position>";
  615. sceneData += "<x>" + recSize.x + "</x>";
  616. sceneData += "<y>" + recSize.y + "</y>";
  617. sceneData += "</position>";
  618. sceneData += "<size>";
  619. sceneData += "<width>" + recSize.width + "</width>";
  620. sceneData += "<height>" + recSize.height + "</height>";
  621. sceneData += "</size>";
  622. cutQuarter(duppedPsd.duplicate(),validFileName);
  623. obj.visible = false;
  624. return;
  625. }
  626. else
  627. {
  628. sceneData += "<imageType>" + "Image" + "</imageType>\n";
  629. }
  630. obj.visible = true;
  631. saveScenePng(duppedPsd.duplicate(), validFileName, true);
  632. obj.visible = false;
  633. }
  634. function hideAllLayers(obj)
  635. {
  636. hideLayerSets(obj);
  637. }
  638. function hideLayerSets(obj)
  639. {
  640. for (var i = obj.layers.length - 1; 0 <= i; i--)
  641. {
  642. if (obj.layers[i].typename == "LayerSet")
  643. {
  644. hideLayerSets(obj.layers[i]);
  645. }
  646. else
  647. {
  648. obj.layers[i].visible = false;
  649. }
  650. }
  651. }
  652. //显示图层组及组下所有图层
  653. function showAllLayers(obj)
  654. {
  655. showLayerSets(obj);
  656. }
  657. function showLayerSets(obj)
  658. {
  659. for (var i = obj.layers.length - 1; 0 <= i; i--)
  660. {
  661. if (obj.layers[i].typename == "LayerSet")
  662. {
  663. showLayerSets(obj.layers[i]);
  664. }
  665. else
  666. {
  667. obj.layers[i].visible = true;
  668. }
  669. }
  670. }
  671. function getLayerRec(psd,notMerge)
  672. {
  673. // we should now have a single art layer if all went well
  674. if (!notMerge){
  675. psd.mergeVisibleLayers();
  676. }
  677. // figure out where the top-left corner is so it can be exported into the scene file for placement in game
  678. // capture current size
  679. var height = psd.height.value;
  680. var width = psd.width.value;
  681. var top = psd.height.value;
  682. var left = psd.width.value;
  683. // trim off the top and left
  684. psd.trim(TrimType.TRANSPARENT, true, true, false, false);
  685. // the difference between original and trimmed is the amount of offset
  686. top -= psd.height.value;
  687. left -= psd.width.value;
  688. // trim the right and bottom
  689. psd.trim(TrimType.TRANSPARENT);
  690. // find center
  691. top += (psd.height.value / 2)
  692. left += (psd.width.value / 2)
  693. // unity needs center of image, not top left
  694. top = -(top - (height / 2));
  695. left -= (width / 2);
  696. height = psd.height.value;
  697. width = psd.width.value;
  698. psd.close(SaveOptions.DONOTSAVECHANGES);
  699. return {
  700. y: top,
  701. x: left,
  702. width: width,
  703. height: height
  704. };
  705. }
  706. function saveScenePng(psd, fileName, writeToDisk,notMerge)
  707. {
  708. // we should now have a single art layer if all went well
  709. if(!notMerge)
  710. {
  711. psd.mergeVisibleLayers();
  712. }
  713. // figure out where the top-left corner is so it can be exported into the scene file for placement in game
  714. // capture current size
  715. var height = psd.height.value;
  716. var width = psd.width.value;
  717. var top = psd.height.value;
  718. var left = psd.width.value;
  719. // trim off the top and left
  720. psd.trim(TrimType.TRANSPARENT, true, true, false, false);
  721. // the difference between original and trimmed is the amount of offset
  722. top -= psd.height.value;
  723. left -= psd.width.value;
  724. // trim the right and bottom
  725. psd.trim(TrimType.TRANSPARENT);
  726. // find center
  727. top += (psd.height.value / 2)
  728. left += (psd.width.value / 2)
  729. // unity needs center of image, not top left
  730. top = -(top - (height / 2));
  731. left -= (width / 2);
  732. height = psd.height.value;
  733. width = psd.width.value;
  734. var rec = {
  735. y: top,
  736. x: left,
  737. width: width,
  738. height: height
  739. };
  740. // save the scene data
  741. if(!notMerge){
  742. sceneData += "<position>";
  743. sceneData += "<x>" + rec.x + "</x>";
  744. sceneData += "<y>" + rec.y + "</y>";
  745. sceneData += "</position>";
  746. sceneData += "<size>";
  747. sceneData += "<width>" + rec.width + "</width>";
  748. sceneData += "<height>" + rec.height + "</height>";
  749. sceneData += "</size>";
  750. }
  751. if (writeToDisk)
  752. {
  753. // save the image
  754. var pngFile = new File(destinationFolder + "/" + fileName + ".png");
  755. var pngSaveOptions = new PNGSaveOptions();
  756. psd.saveAs(pngFile, pngSaveOptions, true, Extension.LOWERCASE);
  757. }
  758. psd.close(SaveOptions.DONOTSAVECHANGES);
  759. }
  760. function makeValidFileName(fileName)
  761. {
  762. var validName = fileName.replace(/^\s+|\s+$/gm, ''); // trim spaces
  763. //删除九宫格关键字符
  764. validName = validName.replace(/\s*_9S(\:\d+)+/g,"")
  765. validName = validName.replace(/[\\\*\/\?:"\|<>]/g, ''); // remove characters not allowed in a file name
  766. validName = validName.replace(/[ ]/g, '_'); // replace spaces with underscores, since some programs still may have troubles with them
  767. if (validName.match("Common") || validName.match("Global"))
  768. {
  769. validName = validName.substring (0,validName.lastIndexOf ("@")); //截取@之后的字符串作为图片的名称。
  770. }
  771. else if(!sourcePsdName.match("Common") || !sourcePsdName.match("Global")) // 判断是否为公用的PSD素材文件,如果不是,则自动为图片增加后缀,防止重名。 公用psd文件的图片层不允许重名。
  772. {
  773. validName += "_" + uuid++;
  774. }
  775. $.writeln(validName);
  776. return validName;
  777. }
  778. /***************************************************************************************************************************************************************************************************************/
  779. //对称的图片处理,切一半
  780. //2017.01.10
  781. //by zs
  782. // 裁切 基于透明像素
  783. function trim(doc){
  784. doc.trim(TrimType.TRANSPARENT,true,true,true,true);
  785. }
  786. // 裁剪左半部分
  787. function cutLeftHalf(doc,layerName){
  788. doc.mergeVisibleLayers();
  789. trim(doc);
  790. var _obj = doc.activeLayer
  791. var width = doc.width;
  792. var height = doc.height;
  793. var side = width / 2;
  794. var region = Array(Array(0,height),Array(0,0),Array(side,0),Array(side,height));
  795. var selectRect = doc.selection.select(region);
  796. doc.selection.copy();
  797. var newStem = doc.paste();
  798. newStem.name = layerName;
  799. var deltaX = 0;
  800. var deltaY = 0;
  801. if(region[0][0] != 0){
  802. deltaX = -(width - side*2);
  803. }
  804. newStem.translate(deltaX,deltaY);
  805. _obj.visible = false;
  806. trim(doc);
  807. saveScenePng(doc, layerName, true,true);
  808. // exportHalfImage(doc,"LeftHalf");
  809. }
  810. // 裁剪下半部分
  811. function cutBottomHalf(doc,layerName){
  812. doc.mergeVisibleLayers();
  813. trim(doc);
  814. var _obj = doc.activeLayer
  815. var width = doc.width;
  816. var height = doc.height;
  817. var side = height / 2;
  818. //var region = Array(Array(0,side),Array(0,0),Array(width,0),Array(width,side));
  819. var region = Array(Array(0,height),Array(0,side),Array(width,side),Array(width,height));
  820. var selectRect = doc.selection.select(region);
  821. doc.selection.copy();
  822. var newStem = doc.paste();
  823. newStem.name = layerName;
  824. var deltaX = 0;
  825. var deltaY = 0;
  826. if (region[0][1] != side){
  827. deltaY = -(height - side*2);
  828. }
  829. newStem.translate(deltaX,deltaY);
  830. _obj.visible = false;
  831. trim(doc);
  832. saveScenePng(doc, layerName, true,true);
  833. //exportHalfImage(doc,"UpHalf");
  834. }
  835. // 裁剪左下四分之一
  836. function cutQuarter(doc,layerName){
  837. doc.mergeVisibleLayers();
  838. trim(doc);
  839. var _obj = doc.activeLayer
  840. var width = doc.width;
  841. var height = doc.height;
  842. var side = height / 2;
  843. var region = Array(Array(0,height),Array(0,height / 2),Array(width / 2,height / 2),Array(width / 2,height));
  844. var selectRect = doc.selection.select(region);
  845. doc.selection.copy();
  846. var newStem = doc.paste();
  847. newStem.name = layerName;
  848. var deltaX = 0;
  849. var deltaY = 0;
  850. if (region[0][1] != side){
  851. deltaY = -(height - side*2);
  852. }
  853. newStem.translate(deltaX,deltaY);
  854. _obj.visible = false;
  855. trim(doc);
  856. saveScenePng(doc, layerName, true,true);
  857. }
  858. function exportHalfImage(psd,halfType)
  859. {
  860. hideAllLayers(psd);
  861. var layerName = "";
  862. for (var i = psd.layers.length - 1; 0 <= i; i--)
  863. {
  864. layerName = psd.layers[i].name;
  865. if(layerName.match(halfType))
  866. {
  867. psd.layers[i].visible = true;
  868. saveScenePng(psd, layerName, true,true);
  869. }
  870. }
  871. }
  872. /***************************************************************************************************************************************************************************************************************/
  873. //九宫格切图
  874. //2017.01.13
  875. //by HuangLang
  876. function _9sliceCutImg(doc,layerName,vaildName){
  877. // 创建图层组
  878. var _obj = doc.activeLayer
  879. var stemGroup = doc.layerSets.add();
  880. stemGroup.name = layerName
  881. // _obj.move(stemGroup,ElementPlacement.PLACEATEND)
  882. doc.mergeVisibleLayers();
  883. trim(doc);
  884. var width = doc.width;
  885. var height = doc.height;
  886. var re = /\s*_9S(\:\d+)+/g;
  887. var getStr = ""
  888. var result = layerName.match(re)
  889. if (result) {
  890. getStr = result[0]
  891. }else{
  892. alert("图层名为:"+layerName+"的九宫格格式不对!应为_9S:XX或:XX:XX:XX:XX");
  893. return;
  894. }
  895. var nums = getStr.split(":")
  896. if ( nums.length == 2) {
  897. for(var j = 0;j<slicePaddingArr.length;j++)
  898. {
  899. sliceOriArr[j] = parseInt(nums[1])
  900. slicePaddingArr[j] = parseInt(nums[1])
  901. }
  902. }
  903. else if ( nums.length == 5)
  904. {
  905. for(var j = 0;j<slicePaddingArr.length;j++)
  906. {
  907. var num = parseInt(nums[j+1])
  908. sliceOriArr[j] = num
  909. if (num == 0 ){
  910. if ((j+1) %2 == 0) {
  911. num = parseInt(height/2)
  912. }else{
  913. num = parseInt(width/2)
  914. }
  915. }
  916. slicePaddingArr[j] = num
  917. }
  918. }else{
  919. alert("图层名为:"+layerName+"的九宫格格式不对!应为_9S:XX或:XX:XX:XX:XX");
  920. return;
  921. }
  922. var _obj = doc.activeLayer
  923. //左下左上,右上右下
  924. var selRegion = Array(
  925. Array(Array(0,slicePaddingArr[1]),Array(0, 0),Array(slicePaddingArr[0] , 0),Array(slicePaddingArr[0], slicePaddingArr[1])),
  926. Array(Array(width-slicePaddingArr[2],slicePaddingArr[1]),Array(width-slicePaddingArr[2], 0),Array(width , 0),Array(width, slicePaddingArr[1])),
  927. Array(Array(0,height),Array(0, height-slicePaddingArr[3]),Array(slicePaddingArr[0] , height-slicePaddingArr[3]),Array(slicePaddingArr[0], height)),
  928. Array(Array(width-slicePaddingArr[2],height),Array(width-slicePaddingArr[2], height-slicePaddingArr[3]),Array(width , height-slicePaddingArr[3]),Array(width, height)),
  929. );
  930. for (var i = 0;i<selRegion.length;i++)
  931. {
  932. doc.activeLayer = _obj;
  933. doc.selection.select(selRegion[i]);
  934. doc.selection.copy();
  935. var newStem = doc.paste();
  936. newStem.name = vaildName;
  937. var deltaX = 0;
  938. var deltaY = 0;
  939. if(selRegion[i][0][0] != 0){
  940. deltaX = - (width - slicePaddingArr[0]-slicePaddingArr[2]);
  941. }
  942. if(selRegion[i][1][1] != 0){
  943. deltaY = - (height - slicePaddingArr[1]-slicePaddingArr[3]);
  944. }
  945. newStem.translate(deltaX,deltaY);
  946. }
  947. _obj.visible = false;
  948. doc.mergeVisibleLayers();
  949. sceneData += "<arguments>";
  950. sceneData += "<string>" + sliceOriArr[0] + "</string>";
  951. sceneData += "<string>" + sliceOriArr[1] + "</string>";
  952. sceneData += "<string>" + sliceOriArr[2] + "</string>";
  953. sceneData += "<string>" + sliceOriArr[3] + "</string>";
  954. sceneData += "</arguments>";
  955. trim(doc);
  956. saveScenePng(doc, vaildName, true,true);
  957. }