forked from vallasd/PLExportLayers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExportLayers.js
558 lines (435 loc) · 16.7 KB
/
ExportLayers.js
1
//// PLExportLayers for Illustrator (Exports layers as individual images)// // Exports all layers as individual image files into chosen directory//// The MIT License (MIT)//// Copyright (c) 2015 David C. Vallas ([email protected]) (dcvallas@twitter)//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in all// copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE// SOFTWARE// Default Variables, change as neededvar docRef = app.activeDocumentvar base_path = docRef.path.fsName;var format = 'PNG 24'; // Make sure this value is the same as initial, search formatList.selection = , 0 = PNG 8, 1 = PNG 24, 2 = JPEGvar scaling = 100.0;var transparency = true;var antiAliasing = true;var iOS = true;var pixelBorder = 2;var dlg = new Window('dialog', 'Export Layers as Individual Files');var originalBounds = docRef.artboards[0].artboardRect;var debug = false;// Window.alert( 'Use this command for debug.' ); function init() { var parse_success = this.load_prefs(); if (parse_success) { this.show_dialog(); }} function load_prefs() { var parse_success = false; // find existing layers or add new one // DO NOTHING, CAN REMOVE VARIABLES var parse_success = true; return parse_success; }function show_dialog() { // Export dialog done at the top // this.dlg = new Window('dialog', 'Export Layers For iOS Application'); // Export Each Layer Pannel var exportPanel = this.dlg.add('panel', undefined, 'Export Each Layer'); // Scaling Row var scaleRow = exportPanel.add('group', undefined, '') scaleRow.oreintation = 'row'; scaleRow.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] var scaleTitle = scaleRow.add('statictext', undefined, 'Scaling:'); scaleTitle.size = [100,20] var scaleField = scaleRow.add('edittext', undefined, this.scaling); scaleField.size = [ 100,20 ]; var scaleDescription = scaleRow.add('statictext', undefined, '(Normally 100%)'); scaleDescription.size = [300,20] // Pixel Border Row var pixelBorderRow = exportPanel.add('group', undefined, '') pixelBorderRow.oreintation = 'row'; pixelBorderRow.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] var pixelTitle = pixelBorderRow.add('statictext', undefined, 'Border Buffer'); pixelTitle.size = [100,20] var pixelField = pixelBorderRow.add('edittext', undefined, this.pixelBorder); pixelField.size = [ 100,20 ]; var pixelDescription = pixelBorderRow.add('statictext', undefined, '(In Pixels)'); pixelDescription.size = [300,20] // Output Directory Row var outputDirectoryRow = exportPanel.add( 'group', undefined, '') outputDirectoryRow.orientation = 'row' outputDirectoryRow.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] var directoryTitle = outputDirectoryRow.add('statictext', undefined, 'Output directory:'); directoryTitle.size = [ 100,20 ]; var directoryField = outputDirectoryRow.add('edittext', undefined, this.base_path); directoryField.size = [ 300,20 ]; var directoryButton = outputDirectoryRow.add('button', undefined, 'Choose ...' ); directoryButton.onClick = function() { directoryField.text = Folder.selectDialog(); }; // Format and Transparency Row var formatRow = exportPanel.add('group', undefined, ''); formatRow.orientation = 'row'; formatRow.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]; var formatTitle = formatRow.add('statictext', undefined, 'Export format:'); formatTitle.size = [ 100,20 ]; var formatList = formatRow.add('dropdownlist', undefined, [ 'PNG 8', 'PNG 24', 'JPG' ]); formatList.selection = 1; formatRow.transparentChk = formatRow.add('checkbox', undefined, 'Transparency'); formatRow.transparentChk.value = this.transparency; formatRow.antiAliasingChk = formatRow.add('checkbox', undefined, 'antiAliasing'); formatRow.antiAliasingChk.value = this.antiAliasing; formatRow.iOSChk = formatRow.add('checkbox', undefined, 'iOS'); formatRow.iOSChk.value = this.iOS; // Progress Row var progBar = exportPanel.add( 'progressbar', undefined, 0, 100 ); progBar.size = [400,10] var progLabel = exportPanel.add('statictext', undefined, '...' ); progLabel.size = [ 400,20 ]; // Ok Cancel Row var btnPnl = this.dlg.add('group', undefined, ''); btnPnl.orientation = 'row' btnPnl.cancelBtn = btnPnl.add('button', undefined, 'Cancel', {name:'cancel'}); btnPnl.cancelBtn.onClick = function() { this.dlg.close() }; // OK button btnPnl.okBtn = btnPnl.add('button', undefined, 'Export', {name:'ok'}); btnPnl.okBtn.onClick = function() { scaling = parseFloat( scaleField.text.replace( /\% /, '' )); format = formatList.selection.text; antiAliasing = formatRow.antiAliasingChk.value; transparency = formatRow.transparentChk.value; iOS = formatRow.iOSChk.value base_path = directoryField.text; pixelBorder = parseInt( pixelField.text.replace( /\% /, '' ) ); exportClicked() }; this.update_export_desc( progLabel ); this.dlg.progLabel = progLabel; this.dlg.progBar = progBar; this.dlg.show();}function exportClicked() { run_export(); this.docRef.artboards[0].artboardRect = this.originalBounds;}function update_export_desc ( progLabel ) { progLabel.text = 'Will export ' + this.docRef.layers.length; this.num_to_export = this.docRef.layers.length;}function setOptions(format, scaling) { var options; if ( this.debug ) { Window.alert( 'transparency: ' + this.transparency + ' antiAliasing: ' + this.antiAliasing + ' iOS: ' + this.iOS + ' scale: ' + this.scaling + ' pixelBorder: ' + this.pixelBorder + ' path: ' + this.base_path ); } if ( format == 'PNG 8' ) { options = new ExportOptionsPNG8(); options.antiAliasing = this.antiAliasing; options.transparency = this.transparency; options.artBoardClipping = true; options.horizontalScale = this.scaling; options.verticalScale = this.scaling; } else if ( format == 'PNG 24' ) { options = new ExportOptionsPNG24(); options.antiAliasing = this.antiAliasing; options.transparency = this.transparency; options.artBoardClipping = true; options.horizontalScale = this.scaling; options.verticalScale = this.scaling; } else if ( format == 'JPG' ) { options = new ExportOptionsJPEG(); options.antiAliasing = this.antiAliasing; options.artBoardClipping = true; options.horizontalScale = this.scaling; options.verticalScale = this.scaling; } return options}function exportImage(filepath, imageBounds, options) { this.docRef.artboards[0].artboardRect = imageBounds; if ( this.format.match( /^PNG/ )) { var destFile = new File( filepath + '.png' ); var export_type = this.format == 'PNG 8' ? ExportType.PNG8 : ExportType.PNG24; this.docRef.exportFile(destFile, export_type , options); } else if ( this.format.match( /^JPG/ )) { var destFile = new File( filepath + '.jpg' ); var export_type = ExportType.JPEG; this.docRef.exportFile(destFile, export_type , options); }}function createImage(filePath, extension, options) { var pb = this.pixelBorder; var bounds = this.docRef.geometricBounds; var boundWithBorder = [bounds[0] - pb, bounds[1] + pb, bounds[2] + pb, bounds[3] - pb]; var completeFilePath = filePath + extension; exportImage(completeFilePath, boundWithBorder, options);}function createRegularImage(filepath, layer, options) { // get layer dimensions var b = this.docRef.geometricBounds; var w = Math.round(Math.abs(b[0] - b[2])); var h = Math.round(Math.abs(b[1] - b[3])); // group and reset size of layer if we have a pixel border if ( this.pixelBorder > 0 ) { setSize(layer, w, h); } // create image createImage(filepath, "", options); // reset layer size, only done if pixelBorder > 0 if ( this.pixelBorder > 0 ) { resetLayer(layer, w, h); } }function createiOSImages(filepath, layer, options) { var b = this.docRef.geometricBounds; var w = Math.round(Math.abs(b[0] - b[2])); var h = Math.round(Math.abs(b[1] - b[3])); var originalPB = this.pixelBorder; // create 1x setSize(layer, w, h); createImage(filepath, "", options); // create 2x setSize(layer, w * 2.0, h * 2.0); multiplyLines(layer, 2.0); createImage(filepath, "@2x", options); multiplyLines(layer, 0.5); // create 3x setSize(layer, w * 3.0, h * 3.0); multiplyLines(layer, 3.0); createImage(filepath, "@3x", options); multiplyLines(layer, (1.0 / 3.0)); // reset layer size resetLayer(layer, w, h)}function createAppIconImages(filepath, layer, options) { var b = this.docRef.geometricBounds; var w = Math.round(Math.abs(b[0] - b[2])); var h = Math.round(Math.abs(b[1] - b[3])); // change pixel border to 0 var px = this.pixelBorder; this.pixelBorder = 0; // create 20pt 1x 2x 3x setSize(layer, 20, 20); multiplyLines(layer, (20 / w)); createImage(filepath, "-20", options); multiplyLines(layer, (w / 20)); setSize(layer, 40, 40); multiplyLines(layer, (40 / w)); createImage(filepath, "-20@2x", options); multiplyLines(layer, (w / 40)); setSize(layer, 60, 60); multiplyLines(layer, (60 / w)); createImage(filepath, "-20@3x", options); multiplyLines(layer, (w / 60)); // create 29pt 1x 2x 3x setSize(layer, 29, 29); multiplyLines(layer, (29 / w)); createImage(filepath, "-29", options); multiplyLines(layer, (w / 29)); setSize(layer, 58, 58); multiplyLines(layer, (58 / w)); createImage(filepath, "-29@2x", options); multiplyLines(layer, (w / 58)); setSize(layer, 87, 87); multiplyLines(layer, (87 / w)); createImage(filepath, "-29@3x", options); multiplyLines(layer, (w / 87)); // create 40pt 1x 2x 3x setSize(layer, 40, 40); multiplyLines(layer, (40 / w)); createImage(filepath, "-40", options); multiplyLines(layer, (w / 40)); setSize(layer, 80, 80); multiplyLines(layer, (80 / w)); createImage(filepath, "-40@2x", options); multiplyLines(layer, (w / 80)); setSize(layer, 120, 120) multiplyLines(layer, (120 / w)); createImage(filepath, "-40@3x", options); multiplyLines(layer, (w / 120)); // create 60pt 2x 3x setSize(layer, 120, 120); multiplyLines(layer, (120 / w)); createImage(filepath, "-60@2x", options); multiplyLines(layer, (w / 120)); setSize(layer, 180, 180); multiplyLines(layer, (180 / w)); createImage(filepath, "-60@3x", options); multiplyLines(layer, (w / 180)); // create 60pt 1x 2x setSize(layer, 76, 76); multiplyLines(layer, (76 / w)); createImage(filepath, "-76", options); multiplyLines(layer, (w / 76)); setSize(layer, 152, 152); multiplyLines(layer, (152 / w)); createImage(filepath, "-76@2x", options); multiplyLines(layer, (w / 152)); // create 83.5pt 2x setSize(layer, 167, 167); multiplyLines(layer, (167 / w)); createImage(filepath, "-83.5@2x", options); multiplyLines(layer, (w / 167)); // create 1024pt 1x setSize(layer, 1024, 1024); multiplyLines(layer, (1024 / w)); createImage(filepath, "-1024", options); multiplyLines(layer, (w / 1024)); // set pixel border back to original this.pixelBorder = px; // reset layer size resetLayer(layer, w, h)}function multiplyLines(layer, multiplier) { // get the page items var items = layer.pageItems; // call recursive update mLines(items, multiplier);}function mLines(items, multiplier) { for ( var i = 0; i < items.length ; i++ ) { var item = items[i]; if ( item.typename == "GroupItem" ) { mLines(item.pageItems, multiplier); } else { item.strokeWidth = item.strokeWidth * multiplier; } }}function resetLayer(layer, width, height) { // set pixelBorder to 0 if ( this.debug == true ) { Window.alert( 'reseting layer: ' + layer.name + ' pixelBorder: ' + this.pixelBorder ); } var px = this.pixelBorder; this.pixelBorder = 0; // set the layer size back to normal width height setSize(layer, width, height); // reset pixelBorder back to normal this.pixelBorder = px; if ( this.debug == true ) { Window.alert( 'reseted layer: ' + layer.name + ' pixelBorder: ' + this.pixelBorder ); }}function groupObjects(layer) { // select all objects on layer var items = layer.pageItems; if ( this.debug == true ) { Window.alert( 'start grouping: ' + layer.name + ' items: ' + items.length ); } // group items if they aren't grouped together already if ( items.length > 1 ) { var newGroup = layer.groupItems.add(); for ( var i = items.length - 1; i > 0 ; i-- ) { var item = items[i]; if ( this.debug == true ) { Window.alert( 'retrieved item name: ' + item); } item.moveToBeginning(newGroup); if ( this.debug == true ) { Window.alert( 'stored item name: ' + item); } } } // deselect the layer if ( this.debug == true ) { Window.alert( 'completed grouping: ' + layer.name + ' items: ' + layer.pageItems.length ); }}function setSize(layer, width, height) { // group items if they aren't already groupObjects(layer); // get all objects, there should only be one var items = layer.pageItems; if ( this.debug == true ) { Window.alert( 'start sizing: ' + layer.name + ' items: ' + items.length ); } // if all objects aren't grouped together, display error and skip if ( items.length == 1 ) { var pb = this.pixelBorder; var item = items[0]; item.width = Math.round(width - (2 * pb)); item.height = Math.round(height - (2 * pb)); if ( this.debug == true ) { Window.alert( 'set sizing: ' + layer.name + ' width: ' + item.width + ' height: ' + item.height ); } } else { if ( this.debug == true ) { Window.alert( 'error sizing: ' + layer.name + '|wasnt grouped| items: ' + items.length ); } }}function run_export() { var num_exported = 0; var options = setOptions(this.format, this.scaling); show_all_layers(); deselect_all_layers(); for ( var j = 0; j < this.docRef.layers.length; j++ ) { hide_all_layers_except(j); var layer = this.docRef.layers[j]; var imagePath = base_path + "/" + layer.name; if ( iOS == true ) { if ( layer.name.indexOf('appicon') !== -1 || layer.name.indexOf('appIcon') !== -1 ) { // create iOS icon images createAppIconImages(imagePath, layer, options); } else { // create iOS images createiOSImages(imagePath, layer, options); } } else { // create regular image createRegularImage(imagePath, layer, options); } num_exported++; dlg.progLabel.text = 'Exported ' + num_exported + ' of ' + this.num_to_export; dlg.progBar.value = num_exported / this.num_to_export * 100; dlg.update(); } app.activeDocument.artboards[0].artboardRect = this.originalBounds; show_all_layers(); this.dlg.close();} function getRealVisibleBounds(grp) { var bounds = []; for(i = grp.pathItems.length - 1; i >=0; i--){ if(grp.pathItems[i].typename == "PathItem" && grp.pathItems[i].clipping) bounds = grp.pathItems[i].visibleBounds; } return (bounds.length == 0) ? null : bounds;} function deselect_all_layers() { for( var i = 0; i < this.docRef.layers.length; i++ ) { layer = docRef.layers[i]; deselectLayer(layer); }}function selectLayer(layer) { // get items from layer var items = layer.pageItems; // select items for ( var i = 0; i < items; i++ ) { items[i].selected = true; } // return items return items}function deselectLayer(layer) { // get items from layer var items = layer.pageItems; // select items for ( var i = 0; i < items; i++ ) { items[i].selected = false; }} function hide_all_layers_except(layerVal) { for( var i = 0; i < this.docRef.layers.length; i++) { layer = docRef.layers[i]; if (i == layerVal) { layer.visible = true; } else { layer.visible = false; } }} function show_all_layers() { for ( var i = 0; i < this.docRef.layers.length; i++) { layer = docRef.layers[i]; layer.visible = true; }}init();