Skip to main content
Participant
March 29, 2023
Answered

Need help to create script that stacks files with the same names together

  • March 29, 2023
  • 3 replies
  • 1140 views

Unfortunately I have little to know scripting knowledge so this is a bit out of my area of expertise for me.

 

I have 360 degree images and to remove the background easily I need a way to stack 3 files together. Normally I would do it manually but there are just too many files for this to be efficient.

 

Inside of each folder I have 3 subfolders, "spin" "spin2" and "spin3". In each folders the file names are the same.

 

I need help creating a script that stacks only similar file names together. So for example it would find in each of the folders "r010_a000.jpg", and put them in a layer stack.

 

Thanks in advance!

This topic has been closed for replies.
Correct answer Stephen Marsh

@djghost1133 

 

I quickly modified an older script from 2 to 3 input folders... I would do things slightly differently today, however, I don't have time at the moment. I'll look at refining the code later based on your feedback.

 

All it does is stack alphabetically sorting files from 3 input folders as a layered PSD. There is no error checking, it is presumed that all three input folders have the same number of files and that they are all named the same.

 

EDIT: Code updated to version 1.1:

 

/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/need-help-to-create-script-that-stacks-files-with-the-same-names-together/m-p/13688339
v1.1 - 30th March 2023, Stephen Marsh
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/auto-merge-files/m-p/10753387
*/

#target photoshop

var folder1 = Folder.selectDialog("Please select the 1st input folder");  // input folder 1
var folder2 = Folder.selectDialog("Please select the 2nd input folder");  // input folder 2 
var folder3 = Folder.selectDialog("Please select the 3rd input folder");  // input folder 3 

var saveFolder = Folder.selectDialog("Please select the folder to save to...");  // output folder
var searchMask = '*.???';
var list1 = folder1.getFiles(searchMask);
var list2 = folder2.getFiles(searchMask);
var list3 = folder3.getFiles(searchMask);
list1.sort(); // Alpha-numeric sort
list2.sort(); // Alpha-numeric sort
list3.sort(); // Alpha-numeric sort

app.displayDialogs = DialogModes.NO;

var psdOptions = new PhotoshopSaveOptions();
psdOptions.embedColorProfile = true;
psdOptions.alphaChannels = true;
psdOptions.layers = true;
psdOptions.spotColors = true;

for (var i = 0; i < list1.length; i++) {
    var doc = open(list1[i]);
    var docName = doc.name;
    activeDocument.activeLayer.name = folder1.name + " - " + docName.split('.')[0];
    placeFile(list2[i], 100);
    activeDocument.activeLayer.rasterize(RasterizeType.ENTIRELAYER);
    activeDocument.activeLayer.name = folder2.name + " - " + activeDocument.activeLayer.name;
    placeFile(list3[i], 100);
    activeDocument.activeLayer.rasterize(RasterizeType.ENTIRELAYER);
    activeDocument.activeLayer.name = folder3.name + " - " + activeDocument.activeLayer.name;
    doc.saveAs(new File(saveFolder + '/' + docName.split('.')[0] + '.psd'), psdOptions);
    doc.close(SaveOptions.DONOTSAVECHANGES);
};

alert('Script completed!' + '\n' + 'Files saved to:' + '\r' + saveFolder.fsName);

function placeFile(file, scale) {
    try {
        var idPlc = charIDToTypeID("Plc ");
        var desc2 = new ActionDescriptor();
        var idnull = charIDToTypeID("null");
        desc2.putPath(idnull, new File(file));
        var idFTcs = charIDToTypeID("FTcs");
        var idQCSt = charIDToTypeID("QCSt");
        var idQcsa = charIDToTypeID("Qcsa");
        desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
        var idOfst = charIDToTypeID("Ofst");
        var desc3 = new ActionDescriptor();
        var idHrzn = charIDToTypeID("Hrzn");
        var idPxl = charIDToTypeID("#Pxl");
        desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
        var idVrtc = charIDToTypeID("Vrtc");
        var idPxl = charIDToTypeID("#Pxl");
        desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
        var idOfst = charIDToTypeID("Ofst");
        desc2.putObject(idOfst, idOfst, desc3);
        var idWdth = charIDToTypeID("Wdth");
        var idPrc = charIDToTypeID("#Prc");
        desc2.putUnitDouble(idWdth, idPrc, scale);
        var idHght = charIDToTypeID("Hght");
        var idPrc = charIDToTypeID("#Prc");
        desc2.putUnitDouble(idHght, idPrc, scale);
        var idAntA = charIDToTypeID("AntA");
        desc2.putBoolean(idAntA, true);
        executeAction(idPlc, desc2, DialogModes.NO);

    }
    catch (e) { }
}//end function placeFile

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save as a plain text format file – .txt
  5. Rename the saved file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see below)

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html#Photoshop

 

3 replies

Stephen Marsh
Community Expert
Community Expert
April 1, 2023

@djghost1133 

 

Here is an updated 1.3 version, you now only need to select the top-level/root folder containing the subfolders named "spin", "spin2" and "spin3" – rather than having to manually select all three spin folders.

 

/*
Stack 3 Input Folder Files to PSD.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/need-help-to-create-script-that-stacks-files-with-the-same-names-together/m-p/13688339
v1.3 - 1st March 2023, Stephen Marsh
*/

#target photoshop

// Set an action to process the stacked layers
var actionName = "Molten Lead"; // Action to run, change as needed
var actionSet = "Default Actions"; // Action set, change as needed

// app.documents.length === 0
if (!app.documents.length) {

    try {

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

        // Main script function
        (function () {

            // Select the top-level/root folder
            var baseFolder = Folder.selectDialog('Please select the top-level/parent folder:');
            if (baseFolder === null) return;

            // Set the input folder paths from the top-level/root folder selection
            var inputFolder1 = Folder(baseFolder + "/" + "spin");
            var inputFolder2 = Folder(baseFolder + "/" + "spin2");
            var inputFolder3 = Folder(baseFolder + "/" + "spin3");

            // Limit the file format input, add or remove as required
            var fileList1 = inputFolder1.getFiles(/\.(png|jpe?g|tif?f|psd|psb)$/i);
            var fileList2 = inputFolder2.getFiles(/\.(png|jpe?g|tif?f|psd|psb)$/i);
            var fileList3 = inputFolder3.getFiles(/\.(png|jpe?g|tif?f|psd|psb)$/i);

            // Force alpha-numeric list sort
            fileList1.sort();
            fileList2.sort();
            fileList3.sort();

            // Validate that the file lists aren't empty
            var inputCount1 = fileList1.length;
            var cancelScript1 = (inputCount1 === 0);
            if (cancelScript1 === true) {
                alert('No input files found in the 1st folder, script cancelled!');
                return;
            }
            var inputCount2 = fileList2.length;
            var cancelScript2 = (inputCount2 === 0);
            if (cancelScript2 === true) {
                alert('No input files found in the 2nd folder, script cancelled!');
                return;
            }
            var inputCount3 = fileList3.length;
            var cancelScript3 = (inputCount3 === 0);
            if (cancelScript3 === true) {
                alert('No input files found in the 3rd folder, script cancelled!');
                return;
            }

            // Validate that the input folders have matching file list quantities
            if (inputCount2 !== inputCount1 || inputCount3 !== inputCount2) {
                alert('The input folders do not contain the same quantities of files, script cancelled!');
                return;
            }

            // Set the output folder
            var outputFolder = inputFolder1.parent;

            // or

            /*
            // Select the output folder
            var outputFolder = Folder.selectDialog("Please select the output folder:");
            if (outputFolder === null) {
                return;
            }
            */

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

            // Open the files
            while (fileList1.length) {
                for (var a = 0; a < 1; a++) {
                    try {
                        app.open(fileList1.pop());
                        app.open(fileList2.pop());
                        if (app.documents[1].name != app.documents[0].name) {
                            alert('Name mismatch in the 2nd folder, script cancelled!');
                            return;
                        }
                        app.open(fileList3.pop());
                        if (app.documents[2].name != app.documents[0].name) {
                            alert('Name mismatch in the 3rd folder, script cancelled!');
                            return;
                        }
                    } catch (e) {}
                }

                // 1st doc
                app.activeDocument = documents[0];
                docNameToLayerName();
                activeDocument.activeLayer.name = inputFolder1.name + " - " + activeDocument.activeLayer.name;

                // Stack the 2nd and 3rd docs
                while (app.documents.length > 1) {
                    // 2nd doc
                    app.activeDocument = documents[1];
                    docNameToLayerName();
                    activeDocument.activeLayer.name = inputFolder2.name + " - " + activeDocument.activeLayer.name;
                    app.activeDocument.activeLayer.duplicate(documents[0]);
                    app.activeDocument = documents[0];
                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                    // 3rd doc
                    app.activeDocument = documents[1];
                    docNameToLayerName();
                    activeDocument.activeLayer.name = inputFolder3.name + " - " + activeDocument.activeLayer.name;
                    app.activeDocument.activeLayer.duplicate(documents[0]);
                    app.activeDocument = documents[0];
                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                }

                try {
                // Run the specified action on the stacked layers
                app.doAction(actionName, actionSet);
                } catch (e) {
                    e + ' ' + e.line;
                }

                // Save name & save path
                var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                var saveFile = File(outputFolder + '/' + docName + '.psd');

                // 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;
                    app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                }

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

            // Restore saved dialogs
            app.displayDialogs = restoreDialogMode;

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

            // 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('Please close all open documents before running this script!');
}

 

 

Stephen Marsh
Community Expert
Community Expert
March 31, 2023

@djghost1133 – Here is a refined 1.2 version (a total rewrite, including basic error checking at key points):

 

* Nominate an action set and action to play on the stacked layers.

 

* No need to set an output folder, the parent folder of the first input folder will be used as the save location

 

/*
Stack 3 Input Folder Files to PSD.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/need-help-to-create-script-that-stacks-files-with-the-same-names-together/m-p/13688339
v1.2 - 31st March 2023, Stephen Marsh
*/

#target photoshop

// Set an action to process the stacked layers
var actionName = "Molten Lead"; // Action to run, change as needed
var actionSet = "Default Actions"; // Action set, change as needed

// app.documents.length === 0
if (!app.documents.length) {

    try {

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

        // Main script function
        (function () {

            // Select the input folders
            var inputFolder1 = Folder.selectDialog('Please select the 1st input folder:');
            if (inputFolder1 === null) return;
            var inputFolder2 = Folder.selectDialog('Please select the 2nd input folder:');
            if (inputFolder2 === null) return;
            var inputFolder3 = Folder.selectDialog('Please select the 3rd input folder:');
            if (inputFolder3 === null) return;

            // Limit the file format input, add or remove as required
            var fileList1 = inputFolder1.getFiles(/\.(png|jpe?g|tif?f|psd|psb)$/i);
            var fileList2 = inputFolder2.getFiles(/\.(png|jpe?g|tif?f|psd|psb)$/i);
            var fileList3 = inputFolder3.getFiles(/\.(png|jpe?g|tif?f|psd|psb)$/i);

            // Force alpha-numeric list sort
            fileList1.sort();
            fileList2.sort();
            fileList3.sort();

            // Validate that the file lists aren't empty
            var inputCount1 = fileList1.length;
            var cancelScript1 = (inputCount1 === 0);
            if (cancelScript1 === true) {
                alert('No input files found in the 1st folder, script cancelled!');
                return;
            }
            var inputCount2 = fileList2.length;
            var cancelScript2 = (inputCount2 === 0);
            if (cancelScript2 === true) {
                alert('No input files found in the 2nd folder, script cancelled!');
                return;
            }
            var inputCount3 = fileList3.length;
            var cancelScript3 = (inputCount3 === 0);
            if (cancelScript3 === true) {
                alert('No input files found in the 3rd folder, script cancelled!');
                return;
            }

            // Validate that the input folders have matching file list quantities
            if (inputCount2 !== inputCount1 || inputCount3 !== inputCount2) {
                alert('The input folders do not contain the same quantities of files, script cancelled!');
                return;
            }

            // Set the output folder
            var outputFolder = inputFolder1.parent + "/";

            // or

            /*
            // Select the output folder
            var outputFolder = Folder.selectDialog("Please select the output folder:");
            if (outputFolder === null) {
                return;
            }
            */

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

            // Open the files
            while (fileList1.length) {
                for (var a = 0; a < 1; a++) {
                    try {
                        app.open(fileList1.pop());
                        app.open(fileList2.pop());
                        if (app.documents[1].name != app.documents[0].name) {
                            alert('Name mismatch in the 2nd folder, script cancelled!');
                            return;
                        }
                        app.open(fileList3.pop());
                        if (app.documents[2].name != app.documents[0].name) {
                            alert('Name mismatch in the 3rd folder, script cancelled!');
                            return;
                        }
                    } catch (e) {}
                }

                // 1st doc
                app.activeDocument = documents[0];
                docNameToLayerName();
                activeDocument.activeLayer.name = inputFolder1.name + " - " + activeDocument.activeLayer.name;

                // Stack the 2nd and 3rd docs
                while (app.documents.length > 1) {
                    // 2nd doc
                    app.activeDocument = documents[1];
                    docNameToLayerName();
                    activeDocument.activeLayer.name = inputFolder2.name + " - " + activeDocument.activeLayer.name;
                    app.activeDocument.activeLayer.duplicate(documents[0]);
                    app.activeDocument = documents[0];
                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                    // 3rd doc
                    app.activeDocument = documents[1];
                    docNameToLayerName();
                    activeDocument.activeLayer.name = inputFolder3.name + " - " + activeDocument.activeLayer.name;
                    app.activeDocument.activeLayer.duplicate(documents[0]);
                    app.activeDocument = documents[0];
                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                }

                // Run the specified action on the stacked layers
                app.doAction(actionName, actionSet);

                // Save name & save path
                var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                var saveFile = File(outputFolder + '/' + docName + '.psd');

                // 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;
                    app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                }

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

            // Restore saved dialogs
            app.displayDialogs = restoreDialogMode;

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

            // 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('Please close all open documents before running this script!');
}

 

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
March 29, 2023

@djghost1133 

 

I quickly modified an older script from 2 to 3 input folders... I would do things slightly differently today, however, I don't have time at the moment. I'll look at refining the code later based on your feedback.

 

All it does is stack alphabetically sorting files from 3 input folders as a layered PSD. There is no error checking, it is presumed that all three input folders have the same number of files and that they are all named the same.

 

EDIT: Code updated to version 1.1:

 

/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/need-help-to-create-script-that-stacks-files-with-the-same-names-together/m-p/13688339
v1.1 - 30th March 2023, Stephen Marsh
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/auto-merge-files/m-p/10753387
*/

#target photoshop

var folder1 = Folder.selectDialog("Please select the 1st input folder");  // input folder 1
var folder2 = Folder.selectDialog("Please select the 2nd input folder");  // input folder 2 
var folder3 = Folder.selectDialog("Please select the 3rd input folder");  // input folder 3 

var saveFolder = Folder.selectDialog("Please select the folder to save to...");  // output folder
var searchMask = '*.???';
var list1 = folder1.getFiles(searchMask);
var list2 = folder2.getFiles(searchMask);
var list3 = folder3.getFiles(searchMask);
list1.sort(); // Alpha-numeric sort
list2.sort(); // Alpha-numeric sort
list3.sort(); // Alpha-numeric sort

app.displayDialogs = DialogModes.NO;

var psdOptions = new PhotoshopSaveOptions();
psdOptions.embedColorProfile = true;
psdOptions.alphaChannels = true;
psdOptions.layers = true;
psdOptions.spotColors = true;

for (var i = 0; i < list1.length; i++) {
    var doc = open(list1[i]);
    var docName = doc.name;
    activeDocument.activeLayer.name = folder1.name + " - " + docName.split('.')[0];
    placeFile(list2[i], 100);
    activeDocument.activeLayer.rasterize(RasterizeType.ENTIRELAYER);
    activeDocument.activeLayer.name = folder2.name + " - " + activeDocument.activeLayer.name;
    placeFile(list3[i], 100);
    activeDocument.activeLayer.rasterize(RasterizeType.ENTIRELAYER);
    activeDocument.activeLayer.name = folder3.name + " - " + activeDocument.activeLayer.name;
    doc.saveAs(new File(saveFolder + '/' + docName.split('.')[0] + '.psd'), psdOptions);
    doc.close(SaveOptions.DONOTSAVECHANGES);
};

alert('Script completed!' + '\n' + 'Files saved to:' + '\r' + saveFolder.fsName);

function placeFile(file, scale) {
    try {
        var idPlc = charIDToTypeID("Plc ");
        var desc2 = new ActionDescriptor();
        var idnull = charIDToTypeID("null");
        desc2.putPath(idnull, new File(file));
        var idFTcs = charIDToTypeID("FTcs");
        var idQCSt = charIDToTypeID("QCSt");
        var idQcsa = charIDToTypeID("Qcsa");
        desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
        var idOfst = charIDToTypeID("Ofst");
        var desc3 = new ActionDescriptor();
        var idHrzn = charIDToTypeID("Hrzn");
        var idPxl = charIDToTypeID("#Pxl");
        desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
        var idVrtc = charIDToTypeID("Vrtc");
        var idPxl = charIDToTypeID("#Pxl");
        desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
        var idOfst = charIDToTypeID("Ofst");
        desc2.putObject(idOfst, idOfst, desc3);
        var idWdth = charIDToTypeID("Wdth");
        var idPrc = charIDToTypeID("#Prc");
        desc2.putUnitDouble(idWdth, idPrc, scale);
        var idHght = charIDToTypeID("Hght");
        var idPrc = charIDToTypeID("#Prc");
        desc2.putUnitDouble(idHght, idPrc, scale);
        var idAntA = charIDToTypeID("AntA");
        desc2.putBoolean(idAntA, true);
        executeAction(idPlc, desc2, DialogModes.NO);

    }
    catch (e) { }
}//end function placeFile

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save as a plain text format file – .txt
  5. Rename the saved file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see below)

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html#Photoshop

 

Participant
March 29, 2023

@Stephen Marsh 

This does exactly what I need. You just saved me a bunch of hours of work. Thanks a ton! 

Stephen Marsh
Community Expert
Community Expert
March 29, 2023

@djghost1133 – You’re welcome, it was only a few minutes of work to modify and test the previous script.

 

Do you have an ongoing need for this script? If so are there any additions or requests etc?