Skip to main content
Participating Frequently
July 17, 2023
Question

Modifying an existing script to suit new objectives

  • July 17, 2023
  • 2 replies
  • 461 views

Hello

 

I have been using the attached script to process my photos thanks to a great community contributor here in these forums.

The script currently performs the following:
Opens pairs of numerically ordered images from one folder and saves them as separate layers in PS files. So a batch of say 100 images would become 50 PS files, with 2 layers each which I can then open and do whatever with.

However lately I have decided to change the way I do my post processing, and I was wondering if someone could assist me in modifying the script to achieve the following:

Instead of opening photo pairs as it does now, I would like Photoshop to open 4 images (numerically ordered by filename) as separate layers and run an action on them, and have Photoshop stay open with all the files in layers. So for example if I had 200 images in the target folder the script would open them 4 at a time in order, run an action on them, and have the 50 files stay open in Photoshop for further editing.

 

Would anyone be able to assist me with this?

This topic has been closed for replies.

2 replies

Stephen Marsh
Community Expert
Community Expert
July 18, 2023

@andrewh85004476 

 

Here is an updated version that will automatically open the PSD files, which hopefully achieves what you wanted in a slightly different way.

 

/* 
Stack 4 Number of Document Sets to Layers - Top Level Folder.jsx
v 1.0, 18th July 2023 - Stephen Marsh

This script requires input files from a single folder to be alpha/numeric sorting in order to stack in the correct set quantity. 
*/

#target photoshop

if (!app.documents.length) {

    try {

        // Save and disable dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;

        // Main script function
        (function () {

            // Select the input folder
            var inputFolder = Folder.selectDialog('Please select the folder with files to process');
            if (inputFolder === null) return;

            // Limit the file format input, add or remove as required
            var fileList = inputFolder.getFiles(/\.(png|jpg|jpeg|tif|tiff|psd|psb)$/i);

            // Force alpha-numeric list sort
            // Use .reverse() for the first filename in the merged file
            // Remove .reverse() for the last filename in the merged file
            fileList.sort().reverse();

            var setQty = 4;

            // Validate that the file list is not empty
            var inputCount = fileList.length;
            var cancelScript1 = (inputCount === 0);
            if (cancelScript1 === true) {
                alert('Zero input files found, script cancelled!');
                return;
            }
            // Validate the input count vs. output count - Thanks to Kukurykus for the advice to test using % modulus
            var cancelScript2 = !(inputCount % setQty);
            alert(inputCount + ' input files stacked into sets of ' + setQty + ' will produce ' + inputCount / setQty + ' output files.');
            // Test if false, then terminate the script
            if (cancelScript2 === false) {
                alert('Script cancelled as the quantity of input files are not evenly divisible by the set quantity.');
                return;
            }

            // Select the output folder
            var outputFolder = Folder.selectDialog("Please select the folder to save to");
            if (outputFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // Set the file processing counter
            var fileCounter = 0;

            // Loop through and open the file sets
            while (fileList.length) {
                // Sets of N quantity files
                for (var a = 0; a < setQty; a++) {
                    try {
                        app.open(fileList.pop());
                    } catch (e) { }
                }

                // Set the base doc layer name
                app.activeDocument = documents[0];
                docNameToLayerName();

                // Stack all open docs to the base doc
                while (app.documents.length > 1) {
                    app.activeDocument = documents[1];
                    docNameToLayerName();
                    app.activeDocument.activeLayer.duplicate(documents[0]);
                    app.activeDocument = documents[0];

                    // Do something to the stacked active layer (blend mode, opacity etc)
                    // app.activeDocument.activeLayer.blendMode = BlendMode.MULTIPLY;

                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                }

                ////////////////////////////////// Start doing stuff //////////////////////////////////
                // app.doAction("Daytime Flash Layer", "01. CP General");
                ////////////////////////////////// Finish doing stuff //////////////////////////////////

                // Delete XMP metadata to reduce final file size of output files
                removeXMP();

                // Save name + suffix & save path
                var Name = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                var saveFile = File(outputFolder + '/' + Name + '_x' + setQty + '-Sets' + '.psd');
                // var saveFile = File(outputFolder + '/' + Name + '_x' + setQty + '-Sets' + '.jpg');

                // Call the save function
                savePSD(saveFile);

                // Close all open files without saving
                while (app.documents.length) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }

                // Increment the file saving counter
                fileCounter++;


                ///// Functions /////

                function savePSD(saveFile) {
                    psdSaveOptions = new PhotoshopSaveOptions();
                    psdSaveOptions.embedColorProfile = true;
                    psdSaveOptions.alphaChannels = true;
                    psdSaveOptions.layers = true;
                    psdSaveOptions.annotations = true;
                    psdSaveOptions.spotColors = true;
                    // Save as
                    app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                }

                function docNameToLayerName() {
                    var layerName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    app.activeDocument.activeLayer.name = layerName;
                }

                function removeXMP() {
                    if (!documents.length) return;
                    if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                    var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
                    XMPUtils.removeProperties(xmp, "", "", XMPConst.REMOVE_ALL_PROPERTIES);
                    app.activeDocument.xmpMetadata.rawData = xmp.serialize();
                }

            }

            // Restore saved dialogs
            app.displayDialogs = restoreDialogMode;

            // Open the stacked PSD files
            var thePSDfiles = outputFolder.getFiles(/-Sets\.psd$/i);
            // thePSDfiles.sort.reverse();
            thePSDfiles.sort();
            for (var i = 0; i < thePSDfiles.length; i++) {
                app.open(File(thePSDfiles[i]));
            }

            // End of script notification
            app.beep();
            alert('Script completed!' + '\n' + fileCounter + ' combined files saved to:' + '\n' + outputFolder.fsName);

        }());

    } catch (e) {
        // Restore saved dialogs
        app.displayDialogs = restoreDialogMode;
        alert("If you see this message, something went wrong!" + "\r" + e + ' ' + e.line);

    }
} else {
    alert('Stack 4 Number of Sets:' + '\n' + 'Please close all open documents before running this script!');
}

 

 

Participating Frequently
July 28, 2023

Worked great thanks a lot Stephen.

 

Only thing is that it places the last image in the set of 4 as the first layer which I can still work with I would just need to modify my actions.

Thanks again!

Stephen Marsh
Community Expert
Community Expert
July 28, 2023
quote

Worked great thanks a lot Stephen.

 

Only thing is that it places the last image in the set of 4 as the first layer which I can still work with I would just need to modify my actions.

Thanks again!


By @andrewh85004476


You could try changing this:

 

fileList.sort().reverse();

 

To this:

 

fileList.sort();

 

To reverse the entire stack order (which may or may not be what you want).

 

But if it is only one layer that needs to be moved, please provide before and after screenshots of the layers panel to clearly illustrate, that way I can modify the script to suit your actions.

 

An action or script could simply move the last layer in the stack to the first, or the first layer in the stack to the last.

Stephen Marsh
Community Expert
Community Expert
July 18, 2023

Hmm, that code looks strangely familiar!

 

First, change:

 

var setQty = 2;

 

From 2 to 4.

 

The easiest way isn't exactly what you are requesting... Let it save out and close the PSD files as the script is designed to do. Then open all the PSD files again. This could be automated.

 

If you need the action to run afterwards on open, disable/remove it from the script and have it run on open or re-saving via Batch, Image Processor, Image Processor Pro or even Script Events Manager.

 

The script would probably need major rewriting to keep documents open. Hard for me, perhaps not challenging for others though.

 

Participating Frequently
July 18, 2023

Fair enough, thanks again Stephen appreciate it!

Stephen Marsh
Community Expert
Community Expert
July 18, 2023

EDIT: Forget my previous comments, I have now tested and here is some updated code for you:

 

/* 

Stack 4 Number of Document Sets to Layers - Top Level Folder.jsx
v 1.0, 18th July 2023 - Stephen Marsh

This script requires input files from a single folder to be alpha/numeric sorting in order to stack in the correct set quantity. 

*/

#target photoshop

if (!app.documents.length) {

    try {

        // Save and disable dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;

        // Main script function
        (function () {

            // Select the input folder
            var inputFolder = Folder.selectDialog('Please select the folder with files to process');
            if (inputFolder === null) return;

            // Limit the file format input, add or remove as required
            var fileList = inputFolder.getFiles(/\.(png|jpg|jpeg|tif|tiff|psd|psb)$/i);

            // Force alpha-numeric list sort
            // Use .reverse() for the first filename in the merged file
            // Remove .reverse() for the last filename in the merged file
            fileList.sort().reverse();

            var setQty = 4;

            // Validate that the file list is not empty
            var inputCount = fileList.length;
            var cancelScript1 = (inputCount === 0);
            if (cancelScript1 === true) {
                alert('Zero input files found, script cancelled!');
                return;
            }
            // Validate the input count vs. output count - Thanks to Kukurykus for the advice to test using % modulus
            var cancelScript2 = !(inputCount % setQty);
            alert(inputCount + ' input files stacked into sets of ' + setQty + ' will produce ' + inputCount / setQty + ' output files.');
            // Test if false, then terminate the script
            if (cancelScript2 === false) {
                alert('Script cancelled as the quantity of input files are not evenly divisible by the set quantity.');
                return;
            }

            // Select the output folder
            var outputFolder = Folder.selectDialog("Please select the folder to save to");
            if (outputFolder === null) {
                alert('Script cancelled!');
                return;
            }

            // Set the file processing counter
            var fileCounter = 0;

            // Loop through and open the file sets
            while (fileList.length) {
                // Sets of N quantity files
                for (var a = 0; a < setQty; a++) {
                    try {
                        app.open(fileList.pop());
                    } catch (e) { }
                }

                // Set the base doc layer name
                app.activeDocument = documents[0];
                docNameToLayerName();

                // Stack all open docs to the base doc
                while (app.documents.length > 1) {
                    app.activeDocument = documents[1];
                    docNameToLayerName();
                    app.activeDocument.activeLayer.duplicate(documents[0]);
                    app.activeDocument = documents[0];

                    // Do something to the stacked active layer (blend mode, opacity etc)
                    // app.activeDocument.activeLayer.blendMode = BlendMode.MULTIPLY;

                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                }

                ////////////////////////////////// Start doing stuff //////////////////////////////////
                // app.doAction("Daytime Flash Layer", "01. CP General");
                ////////////////////////////////// Finish doing stuff //////////////////////////////////

                // Delete XMP metadata to reduce final file size of output files
                removeXMP();

                // Save name + suffix & save path
                var Name = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                var saveFile = File(outputFolder + '/' + Name + '_x' + setQty + '-Sets' + '.psd');
                // var saveFile = File(outputFolder + '/' + Name + '_x' + setQty + '-Sets' + '.jpg');

                // Call the save function
                savePSD(saveFile);

                // Close all open files without saving
                while (app.documents.length) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }

                // Increment the file saving counter
                fileCounter++;


                ///// Functions /////

                function savePSD(saveFile) {
                    psdSaveOptions = new PhotoshopSaveOptions();
                    psdSaveOptions.embedColorProfile = true;
                    psdSaveOptions.alphaChannels = true;
                    psdSaveOptions.layers = true;
                    psdSaveOptions.annotations = true;
                    psdSaveOptions.spotColors = true;
                    // Save as
                    app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                }

                function docNameToLayerName() {
                    var layerName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    app.activeDocument.activeLayer.name = layerName;
                }

                function removeXMP() {
                    if (!documents.length) return;
                    if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                    var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
                    XMPUtils.removeProperties(xmp, "", "", XMPConst.REMOVE_ALL_PROPERTIES);
                    app.activeDocument.xmpMetadata.rawData = xmp.serialize();
                }

            }

            // Restore saved dialogs
            app.displayDialogs = restoreDialogMode;

            // End of script notification
            app.beep();
            alert('Script completed!' + '\n' + fileCounter + ' combined files saved to:' + '\n' + outputFolder.fsName);

            // Open the output folder in the Finder or Explorer
            // outputFolder.execute();

        }());

    } catch (e) {
        // Restore saved dialogs
        app.displayDialogs = restoreDialogMode;
        alert("If you see this message, something went wrong!" + "\r" + e + ' ' + e.line);

    }
}

else {
    alert('Stack 4 Number of Sets:' + '\n' + 'Please close all open documents before running this script!');
}