//#target photoshop /** * Export Layer names into web optimized images * * Author: Aaron McGuire (samcreate.com) * Twitter: @samcreate * * Feel free to share/reuse/modify to your hearts content. Attribution would be nice but * is not required. * */ var wizbang = {}; wizbang.global = { original_doc: app.activeDocument, export_folder: null }; wizbang.util = function () { var self = { rasterizeLayerStyle: function () { var idrasterizeLayer = stringIDToTypeID("rasterizeLayer"); var desc5 = new ActionDescriptor(); var idnull = charIDToTypeID("null"); var ref4 = new ActionReference(); var idLyr = charIDToTypeID("Lyr "); var idOrdn = charIDToTypeID("Ordn"); var idTrgt = charIDToTypeID("Trgt"); ref4.putEnumerated(idLyr, idOrdn, idTrgt); desc5.putReference(idnull, ref4); var idWhat = charIDToTypeID("What"); var idrasterizeItem = stringIDToTypeID("rasterizeItem"); var idlayerStyle = stringIDToTypeID("layerStyle"); desc5.putEnumerated(idWhat, idrasterizeItem, idlayerStyle); executeAction(idrasterizeLayer, desc5, DialogModes.NO); }, getWH: function (layer) { var width = (layer.bounds[2] - layer.bounds[0]); var height = (layer.bounds[3] - layer.bounds[1]); return { w: width, h: height }; }, hexToRgb: function (hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; }, dup_doc: function (w, h, layer, retina, uopt) { app.activeDocument = wizbang.global.original_doc; wizbang.global.original_doc.activeLayer = layer; var activeLay = wizbang.global.original_doc.activeLayer; var newLayer = activeLay.duplicate(); var scale = (retina == true ? 2 : 1); newLayer.name = "Wizurd Spell"; wizbang.global.original_doc.activeLayer = newLayer; newLayer.translate(new UnitValue(0 - newLayer.bounds[0].as('px'), 'px'), new UnitValue(0 - newLayer.bounds[1].as('px'), 'px')); self.resizeLayerInPixels(newLayer, uopt.w, uopt.h, false); if (retina) { newLayer.resize(200, 200, AnchorPosition.TOPLEFT); } newLayer.rasterize(RasterizeType.ENTIRELAYER); wizbang.util.rasterizeLayerStyle(); newLayer.copy(); var myNewDoc = app.documents.add(w * scale, h * scale, 72, "WizurdMagik", NewDocumentMode.RGB, DocumentFill.TRANSPARENT); var targetLayer = myNewDoc.artLayers.add(); myNewDoc.paste(); targetLayer.opacity = activeLay.opacity; myNewDoc.trim(TrimType.TRANSPARENT); app.activeDocument = wizbang.global.original_doc; newLayer.remove(); return myNewDoc; }, trim: function (str) { return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }, resizeLayerInPixels : function(Layer,Width , Height, Constrain){ var startRulerUnits = preferences.rulerUnits; preferences.rulerUnits = Units.PIXELS; var LB = Layer.bounds; var lWidth = 100/(LB[2].value - LB[0].value); var lHeight =100/(LB[3].value - LB[1].value); var NewWidth = lWidth * Width; var NewHeight = lHeight * Height; if(Constrain) NewHeight = NewWidth; Layer.resize(Number(NewWidth),Number(NewHeight),AnchorPosition.MIDDLECENTER); app.preferences.rulerUnits = startRulerUnits; } }; return self; }(); wizbang.imageTypes = function () { var self = { export_png: function (layer, imageName, uopt) { var size = wizbang.util.getWH(layer); //setup for user specified options uopt.png8 = uopt.png8 || false; uopt.matte = uopt.matte || false; uopt.retina = uopt.retina || false; uopt.w = uopt.w || size.w; uopt.h = uopt.h || size.h; var doc = wizbang.util.dup_doc(size.w, size.h, layer, false, uopt); //Options to export to PNG files var options = new ExportOptionsSaveForWeb(); options.format = SaveDocumentType.PNG; options.PNG8 = uopt.png8; if (uopt.matte) { var colors = wizbang.util.hexToRgb(uopt.matte); var matteColor = new RGBColor(); matteColor.red = colors.r; matteColor.green = colors.g; matteColor.blue = colors.b; options.matteColor = matteColor; } options.transparency = uopt.transparency || true; finish(doc, imageName, options, uopt, size, layer); $.writeln("export_png called! name: " + imageName); }, export_jpg: function (layer, imageName, uopt) { var size = wizbang.util.getWH(layer); //setup for user specified options uopt.retina = uopt.retina || false; uopt.quality = uopt.quality || 80; uopt.w = uopt.w || size.w; uopt.h = uopt.h || size.h; var doc = wizbang.util.dup_doc(size.w, size.h, layer, false, uopt); var options = new ExportOptionsSaveForWeb(); options.format = SaveDocumentType.JPEG; options.quality = uopt.quality; finish(doc, imageName, options, uopt, size, layer); $.writeln("export_jpg called! name: " + imageName); }, export_gif: function (layer, imageName, uopt) { var size = wizbang.util.getWH(layer); var options = new ExportOptionsSaveForWeb(); //setup for user specified options uopt.retina = uopt.retina || false; uopt.matte = uopt.matte || false; uopt.w = uopt.w || size.w; uopt.h = uopt.h || size.h; var doc = wizbang.util.dup_doc(size.w, size.h, layer,false, uopt); options.ditherAmount = 0; options.dither = Dither.NOISE; options.palette = Palette.LOCALADAPTIVE; options.format = SaveDocumentType.COMPUSERVEGIF; if (uopt.matte) { var colors = wizbang.util.hexToRgb(uopt.matte); var matteColor = new RGBColor(); matteColor.red = colors.r; matteColor.green = colors.g; matteColor.blue = colors.b; options.matteColor = matteColor; } finish(doc, imageName, options, uopt, size, layer); $.writeln("export_gif called! name: " + imageName); } }; return self; function finish(doc, imageName, options, uopt, size, layer) { wizbang.app.final_save_step(doc, imageName, options); if (uopt.retina) { var retina_doc = wizbang.util.dup_doc(size.w, size.h, layer, true, uopt); wizbang.app.final_save_step(retina_doc, imageName, options, true); } } }(); wizbang.app = function () { var flag = 0; var self = { run: function () { wizbang.global.export_folder = Folder.selectDialog("Select a folder to export images"); if(wizbang.global.export_folder != null){ findImageLayers(activeDocument); $.sleep(2000); alert('Wizbang: Finished Export!'); }else{ alert('Wizbang: Export Canceled!'); } }, final_save_step: function (doc, imageName, options, retina) { app.activeDocument = doc; if (retina) { var first = imageName.substring(0, imageName.length - 4); var last = imageName.substring(imageName.length - 4, imageName.length); imageName = first + '@2x' + last; } imageName = wizbang.util.trim(imageName); doc.exportDocument(File(wizbang.global.export_folder + '/' + imageName), ExportType.SAVEFORWEB, options); doc.close(SaveOptions.DONOTSAVECHANGES); app.activeDocument = wizbang.global.original_doc; } }; return self; function findImageLayers(ref) { // declare local variables var layers = ref.layers; var len = layers.length; for (var i = 0; i < len; i++) { var layer = layers[i]; // if layer is a "group" let's loop through it's contents if (layer.typename == 'LayerSet') { findImageLayers(layer); } else { //check if layer name is an image, if so continue var isImage = new RegExp(/\.(gif|jpg|jpeg|tiff|png)$/i); if (isImage.test(layer.name) && layer.visible) { //let's extract the image name the extendsion off the name and use //use it to concatinate a function name e.g. export_png var name_parts = layer.name.split('.'); var type = name_parts[(name_parts.length - 1)]; var export_function = "export_" + type.toLowerCase(); //let's extract the options the layer name (if any) var options = layer.name.match(/\{(.*?)\}/); var imageName = layer.name.split('}')[1] || layer.name; //let's try to turn the the 'options' string into a real javascript object, else //just make a blank object try { var options = eval("(" + options[0] + ")"); } catch (e) { var options = {}; } //let's try and call our concatinated function name and throw it the layer, and name for processing. try { if (flag == 0) { //flag = 1; wizbang.imageTypes[export_function](layer, imageName, options); } } catch (e) { $.writeln(e); } } //eof else } // eof loop } } }(); //this disables all of our programmed actions from being recorded in photoshop history, as well as init's the app app.activeDocument.suspendHistory('Wizbang Export', 'wizbang.app.run()');