How to merge layers for batch export and optimised for web

What I’m trying to do:

  1. Batch export
  2. Optiimize for web (Jpeg)

My layers structure:

Layer1 — Logo
Layer2 — Adjustment layer (Brightness and Control)
Folder-A
~~ Layer3 — image
~~ Layer4 — image
~~ Layer5 — image
~~ ….. (more layers)
Folder-B
~~ Layer6 — image
~~ Layer7 — image
~~ Layer8 — image
~~ ….. (more layers)

I want to batch export the image layers to individual files and optimized each image for web. I figured I could export layers into individual files and use automate batch action to optimize for web.

I use Export layers as PNG but it doesn’t merge the logo layer with the image layer. I need the logo to appear on each image layer. Is there a way to achieve this?

Answer

I’ve made a script that does almost exactly that (in terms of end result… It doesn’t really merge anything). The thing is, it only supports one source folder at a time.

Export document for each layer inside selected group.jsx.

enter image description here

The way it works:

  1. First it hides all layers in the first level of the selected folder
  2. Then it loops through each of those layers performing these actions on each layer:
    1. Shows the current layer (which can also be a group)
    2. Saves the document
    3. Hides the current layer

So anything outside of the selected group is visible in every single output image.

// Name: Export document for each layer inside selected group.jsx
// Formerly: Export Layers Inside Selected Group.jsx

// Description: Photoshop script that saves the whole document for each top level layer inside the selected group.
// Image example: https://user-images.githubusercontent.com/1164476/49152494-aef8af00-f31b-11e8-80ff-d774e3103eae.png

// https://gist.github.com/joonaspaakko/013a223e94ba0fb9a2a0

#target photoshop

try {
  var doc = app.activeDocument;
    var n = 0;
    var duplicates = {};
}
catch (e) {
  alert( 'Open a document first...' );
}

function processLayers( options) {
    
    var group       = doc.activeLayer;
    var groupLength = group.layers.length;
    
    var visibleArray = [];
    
    // HIDE ALL LAYERS
    for ( var i = 0; i < groupLength; i++ ) {
        visibleArray.push( group.layers[i].visible );
        group.layers[i].visible = false;
    }
    
    // START SAVING
    options.docName = doc.name.split('.')[0]; // Assumes filename contains only one period before the extion.
    for ( var i = 0; i < groupLength; i++ ) {
        
        var layer = group.layers[ i ];
        
        options.layerName = layer.name;
        options.layerIndex = i+1;
        
        layer.visible = true;
        save.file( options );
        layer.visible = false;
        
    }
    
    // RESTORE VISIBILITY
    for ( var i = 0; i < groupLength; i++ ) {
        group.layers[i].visible = visibleArray[i];
    }
    
    doc.activeLayer = group;

    alert('Done!'); // There's no error check so who am I to say if the files were saved, but at least the script is done...
    
}

var save = {
    file: function( options ) {
        
        var saveOptions = {};
        
        for ( var i=0; i < options.fileFormats.length; i++ ) {
            
            var fileformat = options.fileFormats[i];
            var destinationFolder = options.destination + "/" + fileformat.toUpperCase();
            
            makeFolder( destinationFolder ); // If it doesn't exist already...
            
            var filename = '';
            filename += options.prefix;
            filename += options.useLayerName ? options.layerName : options.custonName;
            filename += options.suffix;
            
            // IF FILENAME CONTAINS A DOLLAR SIGN
            if ( filename.match(/\$/) !== null ) {
                filename =  filename.replace('$',options.layerIndex);
            }
            // IF FILENAME DOESN'T HAVE THE DOLLAR SIGN AND A
            // DUPLICATE FILENAME IS FOUND, ADD A NUMBER ANYWAYS.
            else {
                
                if ( typeof duplicates[ fileformat ] == 'undefined' ) {
                    duplicates[ fileformat ] = {};
                }
                
                var duplicateNumber = '';
                if ( typeof duplicates[ fileformat ][ filename ] === 'object' ) {
                    duplicateNumber = ' ' + duplicates[ fileformat ][ filename ].length;
                    duplicates[ fileformat ][ filename ].push( filename );
                }
                else {
                    duplicates[ fileformat ][ filename ] = [ filename ];
                }
                
                filename += duplicateNumber;
            }
            
            doc.saveAs( File( destinationFolder + "/" + filename ), save[ fileformat ](), true );
            
        }
        
    },
    psd: function() {
        
        var psd_saveOpts = new PhotoshopSaveOptions();
        
        psd_saveOpts.layers            = true;
        psd_saveOpts.embedColorProfile = true;
        psd_saveOpts.annotations       = true;
        psd_saveOpts.alphaChannels     = true;
        
        return psd_saveOpts;
        
    },
    pdf: function() {
        
        var presetName = '[High Quality Print]';
        
        var pdf_SaveOpts = new PDFSaveOptions();
        
        pdf_SaveOpts.pDFPreset = presetName;
        
        return pdf_SaveOpts;
        
    },
    jpeg: function() {
        
        var jpg_SaveOpts = new JPEGSaveOptions();
        
        jpg_SaveOpts.matte   = MatteType.WHITE;
        jpg_SaveOpts.quality = 10;
        jpg_SaveOpts.formatOptions.STANDARDBASELINE;
        
        return jpg_SaveOpts;
        
    },
    png: function() {
        
        var png_SaveOpts = new PNGSaveOptions();
        
        png_SaveOpts.compression = 9;
        png_SaveOpts.interlaced = false;
        
        return png_SaveOpts;
        
    },
    tiff: function() {
        
        var tiff_SaveOpts = new TiffSaveOptions();
        
        tiff_SaveOpts.alphaChannels      = true;
        tiff_SaveOpts.annotations        = true;
        tiff_SaveOpts.imageCompression   = TIFFEncoding.JPEG;
        tiff_SaveOpts.interleaveChannels = true;
        tiff_SaveOpts.jpegQuality        = 10;
        tiff_SaveOpts.layers             = true;
        tiff_SaveOpts.layerCompression   = LayerCompression.ZIP;
        tiff_SaveOpts.transparency       = true;
        
        return tiff_SaveOpts;
        
    }
};

function makeFolder( path ) {
  var newFolder = Folder( path );
  if( !newFolder.exists ) newFolder.create();
}

if ( app.documents.length > 0 ) {
  if ( app.activeDocument.activeLayer.layers ) {
        init();
  }
  else {
    alert( "Error: \nSelect a parent group of the layers you want to export.")
  }
}

function init() {
    
    /*
    Code for Import https://scriptui.joonas.me — (Triple click to select):
    {"items":{"item-0":{"id":0,"type":"Dialog","parentId":false,"style":{"text":"Export document for each layer inside selected group.jsx","preferredSize":[0,0],"margins":16,"orientation":"column","spacing":10,"alignChildren":["center","top"]}},"item-1":{"id":1,"type":"Checkbox","parentId":6,"style":{"text":"PSD","preferredSize":[0,0],"alignment":null}},"item-2":{"id":2,"type":"Checkbox","parentId":6,"style":{"text":"TIFF","preferredSize":[0,0],"alignment":null}},"item-3":{"id":3,"type":"Checkbox","parentId":6,"style":{"text":"JPEG","preferredSize":[0,0],"alignment":null,"checked":true}},"item-4":{"id":4,"type":"Checkbox","parentId":6,"style":{"text":"PNG","preferredSize":[0,0],"alignment":null}},"item-5":{"id":5,"type":"Checkbox","parentId":6,"style":{"text":"PDF","preferredSize":[0,0],"alignment":null}},"item-6":{"id":6,"type":"Panel","parentId":9,"style":{"text":"","preferredSize":[0,0],"margins":10,"orientation":"row","spacing":10,"alignChildren":["center","top"],"alignment":null}},"item-7":{"id":7,"type":"Panel","parentId":9,"style":{"text":"","preferredSize":[0,0],"margins":10,"orientation":"column","spacing":10,"alignChildren":["left","top"],"alignment":null}},"item-8":{"id":8,"type":"EditText","parentId":14,"style":{"text":"","preferredSize":[90,0],"alignment":null}},"item-9":{"id":9,"type":"Group","parentId":0,"style":{"preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["fill","top"],"alignment":null}},"item-10":{"id":10,"type":"Group","parentId":0,"style":{"preferredSize":[0,0],"margins":[15,0,10,0],"orientation":"row","spacing":10,"alignChildren":["left","top"],"alignment":null}},"item-11":{"id":11,"type":"Button","parentId":10,"style":{"text":"Save","justify":"center","preferredSize":[0,0],"alignment":null}},"item-12":{"id":12,"type":"Button","parentId":10,"style":{"text":"Cancel","justify":"center","preferredSize":[0,0],"alignment":null}},"item-13":{"id":13,"type":"StaticText","parentId":14,"style":{"text":"Prefix:","justify":"left","preferredSize":[0,0],"alignment":null}},"item-14":{"id":14,"type":"Group","parentId":22,"style":{"preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","top"],"alignment":null}},"item-15":{"id":15,"type":"Checkbox","parentId":7,"style":{"text":"Use layer name","preferredSize":[0,0],"alignment":null,"checked":false}},"item-16":{"id":16,"type":"Group","parentId":22,"style":{"preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","top"],"alignment":null}},"item-17":{"id":17,"type":"StaticText","parentId":16,"style":{"text":"Custom name:","justify":"left","preferredSize":[0,0],"alignment":null}},"item-18":{"id":18,"type":"EditText","parentId":16,"style":{"text":"File Name ","preferredSize":[160,0],"alignment":null}},"item-19":{"id":19,"type":"Group","parentId":22,"style":{"preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","top"],"alignment":null}},"item-20":{"id":20,"type":"StaticText","parentId":19,"style":{"text":"Suffix:","justify":"left","preferredSize":[0,0],"alignment":null}},"item-21":{"id":21,"type":"EditText","parentId":19,"style":{"text":"","preferredSize":[90,0],"alignment":null}},"item-22":{"id":22,"type":"Group","parentId":7,"style":{"preferredSize":[0,0],"margins":0,"orientation":"row","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-23":{"id":23,"type":"Divider","parentId":7,"style":false},"item-24":{"id":24,"type":"StaticText","parentId":7,"style":{"text":"Dollar symbol ($) is replaced with incremental numbers","justify":"left","preferredSize":[0,0],"alignment":"center"}}},"order":[0,9,7,15,23,22,14,13,8,16,17,18,19,20,21,24,6,3,4,1,5,2,10,12,11],"activeId":10}
    */

    // DIALOG
    // ======
    var dialog = new Window("dialog");
        dialog.text = "Export document for each layer inside selected group.jsx";
        dialog.orientation = "column";
        dialog.alignChildren = ["center","top"];
        dialog.spacing = 10;
        dialog.margins = 16;

    // GROUP1
    // ======
    var group1 = dialog.add("group");
        group1.orientation = "column";
        group1.alignChildren = ["fill","top"];
        group1.spacing = 10;
        group1.margins = 0;

    // PANEL1
    // ======
    var panel1 = group1.add("panel");
        panel1.orientation = "column";
        panel1.alignChildren = ["left","top"];
        panel1.spacing = 10;
        panel1.margins = 10;

    var checkbox1 = panel1.add("checkbox");
        checkbox1.text = "Use layer name";

    var divider1 = panel1.add("panel");
        divider1.alignment = "fill";

    // GROUP2
    // ======
    var group2 = panel1.add("group");
        group2.orientation = "row";
        group2.alignChildren = ["left","center"];
        group2.spacing = 10;
        group2.margins = 0;

    // GROUP3
    // ======
    var group3 = group2.add("group");
        group3.orientation = "column";
        group3.alignChildren = ["left","top"];
        group3.spacing = 10;
        group3.margins = 0;

    var statictext1 = group3.add("statictext");
        statictext1.text = "Prefix:";

    var edittext1 = group3.add("edittext");
        edittext1.minimumSize.width = 90;

    // GROUP4
    // ======
    var group4 = group2.add("group");
        group4.orientation = "column";
        group4.alignChildren = ["left","top"];
        group4.spacing = 10;
        group4.margins = 0;

    var statictext2 = group4.add("statictext");
        statictext2.text = "Custom name:";

    var edittext2 = group4.add("edittext");
        edittext2.text = "File Name ";
        edittext2.minimumSize.width = 160;

    // GROUP5
    // ======
    var group5 = group2.add("group");
        group5.orientation = "column";
        group5.alignChildren = ["left","top"];
        group5.spacing = 10;
        group5.margins = 0;

    var statictext3 = group5.add("statictext");
        statictext3.text = "Suffix:";

    var edittext3 = group5.add("edittext");
        edittext3.minimumSize.width = 90;

    // PANEL1
    // ======
    var statictext4 = panel1.add("statictext");
        statictext4.text = "Dollar symbol ($) is replaced with incremental numbers";
        statictext4.alignment = ["center","top"];

    // PANEL2
    // ======
    var panel2 = group1.add("panel");
        panel2.orientation = "row";
        panel2.alignChildren = ["center","top"];
        panel2.spacing = 10;
        panel2.margins = 10;

    var checkbox2 = panel2.add("checkbox");
        checkbox2.text = "JPEG";
        checkbox2.value = true;

    var checkbox3 = panel2.add("checkbox");
        checkbox3.text = "PNG";

    var checkbox4 = panel2.add("checkbox");
        checkbox4.text = "PSD";

    var checkbox5 = panel2.add("checkbox");
        checkbox5.text = "PDF";

    var checkbox6 = panel2.add("checkbox");
        checkbox6.text = "TIFF";

    // GROUP6
    // ======
    var group6 = dialog.add("group");
        group6.orientation = "row";
        group6.alignChildren = ["left","top"];
        group6.spacing = 10;
        group6.margins = [0,15,0,10];

    var button1 = group6.add("button", undefined, undefined, {name:"cancel"});
        button1.text = "Cancel";
        button1.justify = "center";

    var button2 = group6.add("button", undefined, undefined, {name:"ok"});
        button2.text = "Save";
        button2.justify = "center";
  
    
    // DIALOG CUSTOMIZATION
    var filename = edittext2;
    filename.text = app.activeDocument.name.split()[0]; // Assumes filename contains only one period before the extion.
    filename.active = true;
    
  var useLayerName = checkbox1;
  useLayerName.onClick = function() {
    var check = this.value;
    var customName = edittext2;
    if ( check ) customName.enabled = !check;
    else customName.enabled = !check;
  };
  
  var cancelBtn = button1;
  cancelBtn.onClick = function() {
        dialog.close();
  };
  
  var saveBtn = button2;
  saveBtn.onClick = function() {
        n = ++n;
        if ( n === 1 ) {
            
        var formatsArray = [];
        var formats = panel2.children;
        for (var i = 0; i < formats.length; i++) {
                var format = formats[i];
                if ( format.value ) {
                    formatsArray.push( format.text.toLowerCase() );
                }
        }
            
            var path = '';
            try { path = doc.path; } catch(e) {}
            
        var options = {
          useLayerName: useLayerName.value,
          fileFormats: formatsArray,
          prefix: edittext1.text,
          custonName: edittext2.text,
          suffix: edittext3.text,
                destination: Folder.selectDialog( 'Select destination folder...', path )
        };
        
        dialog.close();
        
            if ( options.destination ) {
                processLayers( options );
            }
            
        }
  };
    
    dialog.show();
    
}

Attribution
Source : Link , Question Author : FlyingPenguin , Answer Author : Joonas

Leave a Comment