• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
1

How to merge 3 images togehter stacked in a batch?

Participant ,
Jul 08, 2023 Jul 08, 2023

Copy link to clipboard

Copied

I have a bunch of images that I have to manually merge in stacks of 3 together every time. They are all ordered by an alphanumeric filename, so I'm wondering if it's possible to merge them stacked automatically in a batch process in a way that I can set the name of the files so they are named and numbered correctly in a folder.

The images are all the same size, 3840 x 2160 and the stacked image is always the merged size of the images one beneath the other in a stack of three, 3840 x 6480, I have some images as an example. Is it possible to do it in a batch or at least semi-automatically in an action?

TOPICS
Actions and scripting , Windows

Views

1.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jul 12, 2023 Jul 12, 2023
quote

3  I can do with a File renamer so it's the least important one, please if you can do it without number 3


By @HeyoThere

 

Here is an updated 1.1 version, saving to a "Render" sub-folder in the input folder as PNG using a prompt for the base file name with zero padding sequential numbering:

 

/* 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-merge-3-images-togehter-stacked-in-a-batch/td-p/13922876
Stack 3 Document Sets to Vertically Stacked Layers.jsx
Stephen Marsh
v1.1
...

Votes

Translate

Translate
Adobe
Community Expert ,
Jul 08, 2023 Jul 08, 2023

Copy link to clipboard

Copied

@HeyoThere 

 

You will need a script, such as here:

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-automatically-add-two-images-i...


Simply change the default setQty variable from 2 to 3.

 

var setQty = 2;

 

This will stack one layer over the other in sets of 3 images.

 

A simple action can be created to make the canvas 300% in height and to move the layers into vertical position:

 

atn.png

 

The script has placeholder code to run a named action set and action before saving.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 08, 2023 Jul 08, 2023

Copy link to clipboard

Copied

@HeyoThere 

 

The following script is complete for your use case, no need for an action to be run by the script:

 

/* 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-merge-3-images-togehter-stacked-in-a-batch/td-p/13922876
Stack 3 Document Sets to Vertically Stacked Layers.jsx
Stephen Marsh
9th July 2023

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 .sort.reverse() for the first filename in the merged file
            // Use .sort() for the last filename in the merged file
            fileList.sort();

            var setQty = 3;

            // 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;
            }

            // or

            /*
            // Create the output sub-directory
            var outputFolder = Folder(decodeURI(inputFolder + '/Output Sets Folder'));
            if (!outputFolder.exists) outputFolder.create();
            */

            // 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];
                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                }

                ////////////////////////////////// Start doing stuff //////////////////////////////////

                var idcanvasSize = stringIDToTypeID( "canvasSize" );
                var desc295 = new ActionDescriptor();
                var idheight = stringIDToTypeID( "height" );
                var idpercentUnit = stringIDToTypeID( "percentUnit" );
                desc295.putUnitDouble( idheight, idpercentUnit, 300.000000 );
                var idvertical = stringIDToTypeID( "vertical" );
                var idverticalLocation = stringIDToTypeID( "verticalLocation" );
                var idtop = stringIDToTypeID( "top" );
                desc295.putEnumerated( idvertical, idverticalLocation, idtop );
                executeAction(idcanvasSize, desc295, DialogModes.NO);

                activeDocument.selection.selectAll();

                var idselect = stringIDToTypeID( "select" );
                    var desc393 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref95 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idbackwardEnum = stringIDToTypeID( "backwardEnum" );
                        ref95.putEnumerated( idlayer, idordinal, idbackwardEnum );
                    desc393.putReference( idnull, ref95 );
                    var idmakeVisible = stringIDToTypeID( "makeVisible" );
                    desc393.putBoolean( idmakeVisible, false );
                    var idlayerID = stringIDToTypeID( "layerID" );
                        var list14 = new ActionList();
                        list14.putInteger( 3 );
                    desc393.putList( idlayerID, list14 );
                executeAction(idselect, desc393, DialogModes.NO);

                var idalign = stringIDToTypeID( "align" );
                    var desc396 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref96 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idtargetEnum = stringIDToTypeID( "targetEnum" );
                        ref96.putEnumerated( idlayer, idordinal, idtargetEnum );
                    desc396.putReference( idnull, ref96 );
                    var idusing = stringIDToTypeID( "using" );
                    var idalignDistributeSelector = stringIDToTypeID( "alignDistributeSelector" );
                    var idADSCentersV = stringIDToTypeID( "ADSCentersV" );
                    desc396.putEnumerated( idusing, idalignDistributeSelector, idADSCentersV );
                    var idalignToCanvas = stringIDToTypeID( "alignToCanvas" );
                    desc396.putBoolean( idalignToCanvas, false );
                executeAction(idalign, desc396, DialogModes.NO);

                var idselect = stringIDToTypeID( "select" );
                    var desc393 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref95 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idbackwardEnum = stringIDToTypeID( "backwardEnum" );
                        ref95.putEnumerated( idlayer, idordinal, idbackwardEnum );
                    desc393.putReference( idnull, ref95 );
                    var idmakeVisible = stringIDToTypeID( "makeVisible" );
                    desc393.putBoolean( idmakeVisible, false );
                    var idlayerID = stringIDToTypeID( "layerID" );
                        var list14 = new ActionList();
                        list14.putInteger( 3 );
                    desc393.putList( idlayerID, list14 );
                executeAction(idselect, desc393, DialogModes.NO);

                var idalign = stringIDToTypeID( "align" );
                    var desc399 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref98 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idtargetEnum = stringIDToTypeID( "targetEnum" );
                        ref98.putEnumerated( idlayer, idordinal, idtargetEnum );
                    desc399.putReference( idnull, ref98 );
                    var idusing = stringIDToTypeID( "using" );
                    var idalignDistributeSelector = stringIDToTypeID( "alignDistributeSelector" );
                    var idADSBottoms = stringIDToTypeID( "ADSBottoms" );
                    desc399.putEnumerated( idusing, idalignDistributeSelector, idADSBottoms );
                    var idalignToCanvas = stringIDToTypeID( "alignToCanvas" );
                    desc399.putBoolean( idalignToCanvas, false );
                executeAction(idalign, desc399, DialogModes.NO);

                activeDocument.selection.deselect();

                ////////////////////////////////// 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);
                //saveTIFF(saveFile);
                //saveJPEG(saveFile);
                //savePNG(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);
                }

                /* Not currently used, a placeholder to swap in/out as needed
                function saveTIFF(saveFile) {
                    tiffSaveOptions = new TiffSaveOptions();
                    tiffSaveOptions.embedColorProfile = true;
                    tiffSaveOptions.byteOrder = ByteOrder.IBM;
                    tiffSaveOptions.transparency = true;
                    // Change layers to false to save without layers
                    tiffSaveOptions.layers = true;
                    tiffSaveOptions.layerCompression = LayerCompression.ZIP;
                    tiffSaveOptions.interleaveChannels = true;
                    tiffSaveOptions.alphaChannels = true;
                    tiffSaveOptions.annotations = true;
                    tiffSaveOptions.spotColors = true;
                    tiffSaveOptions.saveImagePyramid = false;
                    // Image compression = NONE | JPEG | TIFFLZW | TIFFZIP
                    tiffSaveOptions.imageCompression = TIFFEncoding.TIFFLZW;
                    // Save as
                    app.activeDocument.saveAs(saveFile, tiffSaveOptions, true, Extension.LOWERCASE);
                }
                */

                /* Not currently used, a placeholder to swap in/out as needed
                function saveJPEG(saveFile) {
                    jpgSaveOptions = new JPEGSaveOptions();
                    jpgSaveOptions.embedColorProfile = true;
                    jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
                    jpgSaveOptions.matte = MatteType.NONE;
                    jpgSaveOptions.quality = 10;
                    // Save as
                    activeDocument.saveAs(saveFile, jpgSaveOptions, true, Extension.LOWERCASE);
                }
                */

                /* Not currently used, a placeholder to swap in/out as needed
                function savePNG(saveFile) {
                    var pngOptions = new PNGSaveOptions();
                    pngOptions.compression = 0; // 0-9
                    pngOptions.interlaced = false;
                    // Save as
                    app.activeDocument.saveAs(saveFile, pngOptions, 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 3 Document Sets to Vertically Stacked Layers:' + '\n' + 'Please close all open documents before running this script!');
}

 

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

 

I'm happy to make changes as needed if further refinement is required.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 10, 2023 Jul 10, 2023

Copy link to clipboard

Copied

Thank you, this is pretty much what I needed. If I may tell you just 3 refinements that would make the script even better for me:
1- The script asks me to select a folder where I want the new files to be saved. If possible I'd like the files to automatically be sorted out in a subfolder that would be created inside the folder where the original images were. The subfolder can be called Render.
2 - The files are being saved as PSD files, if possible I'd like them to be saved as PNGs
3-  The file names being choosen are the "name of the third image being stacked" + "_x3-Sets", is it possible for the script to ask me a string to name the generated files and number them with "_0001" and so on?
Basically ask me for to type a name, if I type FileS1 it will name the first file generated would be called FileS1_0001 and the second FileS1_0002 and so on...

Again thank you for the help, you're amazing!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 12, 2023 Jul 12, 2023

Copy link to clipboard

Copied

@HeyoThere 

 

Requests 1 and 2 are easy enough.

 

Request 3 is possible but possibly more complicated.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 12, 2023 Jul 12, 2023

Copy link to clipboard

Copied

3  I can do with a File renamer so it's the least important one, please if you can do it without number 3

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 12, 2023 Jul 12, 2023

Copy link to clipboard

Copied

quote

3  I can do with a File renamer so it's the least important one, please if you can do it without number 3


By @HeyoThere

 

Here is an updated 1.1 version, saving to a "Render" sub-folder in the input folder as PNG using a prompt for the base file name with zero padding sequential numbering:

 

/* 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-merge-3-images-togehter-stacked-in-a-batch/td-p/13922876
Stack 3 Document Sets to Vertically Stacked Layers.jsx
Stephen Marsh
v1.1 - 13th July 2023

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 .sort.reverse() for the first filename in the merged file
            // Use .sort() for the last filename in the merged file
            fileList.sort();

            var setQty = 3;

            // 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;
            }

            // Create the output sub-directory
            var outputFolder = Folder(decodeURI(inputFolder + '/Render'));
            if (!outputFolder.exists) outputFolder.create();

            // File name prompt
            var Name = prompt("Enter the base filename", "");
          
            // Set the file processing counter
            var fileCounter = 0;
          
            // Set the sequential numbering
            var numberLength = 4; // 1 to remove zero padding
            var numberNo = 1; // Start number

            // 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];
                    app.documents[1].close(SaveOptions.DONOTSAVECHANGES);
                }

                ////////////////////////////////// Start doing stuff //////////////////////////////////

                var idcanvasSize = stringIDToTypeID( "canvasSize" );
                var desc295 = new ActionDescriptor();
                var idheight = stringIDToTypeID( "height" );
                var idpercentUnit = stringIDToTypeID( "percentUnit" );
                desc295.putUnitDouble( idheight, idpercentUnit, 300.000000 );
                var idvertical = stringIDToTypeID( "vertical" );
                var idverticalLocation = stringIDToTypeID( "verticalLocation" );
                var idtop = stringIDToTypeID( "top" );
                desc295.putEnumerated( idvertical, idverticalLocation, idtop );
                executeAction(idcanvasSize, desc295, DialogModes.NO);

                activeDocument.selection.selectAll();

                var idselect = stringIDToTypeID( "select" );
                    var desc393 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref95 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idbackwardEnum = stringIDToTypeID( "backwardEnum" );
                        ref95.putEnumerated( idlayer, idordinal, idbackwardEnum );
                    desc393.putReference( idnull, ref95 );
                    var idmakeVisible = stringIDToTypeID( "makeVisible" );
                    desc393.putBoolean( idmakeVisible, false );
                    var idlayerID = stringIDToTypeID( "layerID" );
                        var list14 = new ActionList();
                        list14.putInteger( 3 );
                    desc393.putList( idlayerID, list14 );
                executeAction(idselect, desc393, DialogModes.NO);

                var idalign = stringIDToTypeID( "align" );
                    var desc396 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref96 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idtargetEnum = stringIDToTypeID( "targetEnum" );
                        ref96.putEnumerated( idlayer, idordinal, idtargetEnum );
                    desc396.putReference( idnull, ref96 );
                    var idusing = stringIDToTypeID( "using" );
                    var idalignDistributeSelector = stringIDToTypeID( "alignDistributeSelector" );
                    var idADSCentersV = stringIDToTypeID( "ADSCentersV" );
                    desc396.putEnumerated( idusing, idalignDistributeSelector, idADSCentersV );
                    var idalignToCanvas = stringIDToTypeID( "alignToCanvas" );
                    desc396.putBoolean( idalignToCanvas, false );
                executeAction(idalign, desc396, DialogModes.NO);

                var idselect = stringIDToTypeID( "select" );
                    var desc393 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref95 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idbackwardEnum = stringIDToTypeID( "backwardEnum" );
                        ref95.putEnumerated( idlayer, idordinal, idbackwardEnum );
                    desc393.putReference( idnull, ref95 );
                    var idmakeVisible = stringIDToTypeID( "makeVisible" );
                    desc393.putBoolean( idmakeVisible, false );
                    var idlayerID = stringIDToTypeID( "layerID" );
                        var list14 = new ActionList();
                        list14.putInteger( 3 );
                    desc393.putList( idlayerID, list14 );
                executeAction(idselect, desc393, DialogModes.NO);

                var idalign = stringIDToTypeID( "align" );
                    var desc399 = new ActionDescriptor();
                    var idnull = stringIDToTypeID( "null" );
                        var ref98 = new ActionReference();
                        var idlayer = stringIDToTypeID( "layer" );
                        var idordinal = stringIDToTypeID( "ordinal" );
                        var idtargetEnum = stringIDToTypeID( "targetEnum" );
                        ref98.putEnumerated( idlayer, idordinal, idtargetEnum );
                    desc399.putReference( idnull, ref98 );
                    var idusing = stringIDToTypeID( "using" );
                    var idalignDistributeSelector = stringIDToTypeID( "alignDistributeSelector" );
                    var idADSBottoms = stringIDToTypeID( "ADSBottoms" );
                    desc399.putEnumerated( idusing, idalignDistributeSelector, idADSBottoms );
                    var idalignToCanvas = stringIDToTypeID( "alignToCanvas" );
                    desc399.putBoolean( idalignToCanvas, false );
                executeAction(idalign, desc399, DialogModes.NO);

                activeDocument.selection.deselect();

                ////////////////////////////////// Finish doing stuff //////////////////////////////////

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

                // Save path, name + zero pad suffix
                var saveFile = File(outputFolder + '/' + Name + "_" + zeroPad(numberNo, numberLength) + '.png');
                // Increment the file number
                numberNo++;
                // Call the save function
                savePNG(saveFile);

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

                // Increment the file saving counter
                fileCounter++;

              
                ///// Functions /////

                function savePNG(saveFile) {
                    var pngOptions = new PNGSaveOptions();
                    pngOptions.compression = 0; // 0-9
                    pngOptions.interlaced = false;
                    // Save as
                    app.activeDocument.saveAs(saveFile, pngOptions, 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();
                }

            }
          
          function zeroPad(num, digit) {
            var tmp = num.toString();
            while (tmp.length < digit) {
              tmp = "0" + tmp;
            }
            return tmp;
          }

            // 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 3 Document Sets to Vertically Stacked Layers:' + '\n' + 'Please close all open documents before running this script!');
}

 

 

NOTE: I am not currently checking for or cleaning illegal characters in the file base name.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

@Stephen Marsh 

It's awesome that it's even possible to an automatic naming, something happened with the new script though. I don't know if I did something wrong but in this new script is saves the files all backwards, that meaning the last 3 images sorted in an alpha numeric number become the first new stacked image on the new files (their position on the canvas are still correct though). On the previous script the files were being made correctly. The script even renders the images backwards, it starts with the last images and the previous one started with the first images, so I don't know what is happening there.
Except for that everything is working correctly.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

I didn't intentionally change any code that would have affected file processing sequence or layer stacking order. I had a quick look and couldn't see any differences that would account for this.

 

You could try changing from:

fileList.sort();

 

To:

fileList.sort().reverse();

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

Nice scripting, @Stephen Marsh !

 

Jane

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

LATEST

You can use a scripting language like Python to achieve this. Here's a step-by-step approach:

Install the required libraries by running the following command in your terminal:

pip install numpy opencv-python

 

  1. Create a new Python script in the same directory where your images are stored. Let's name it image_merge.py.
  2. Open image_merge.py in a text editor and add the following code: 
import os
import cv2
import numpy as np

# Set the input and output directories
input_dir = 'input_images/'
output_dir = 'output_images/'

# Create the output directory if it doesn't exist
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# Get the list of image filenames in the input directory
image_files = sorted([f for f in os.listdir(input_dir) if f.endswith('.jpg')])

# Iterate over the image files and merge them in stacks of three
for i in range(0, len(image_files), 3):
    # Load the three images
    image1 = cv2.imread(os.path.join(input_dir, image_files[i]))
    image2 = cv2.imread(os.path.join(input_dir, image_files[i + 1]))
    image3 = cv2.imread(os.path.join(input_dir, image_files[i + 2]))

    # Stack the images vertically
    merged_image = np.vstack((image1, image2, image3))

    # Save the merged image with a new name
    output_filename = f"merged_{i // 3}.jpg"
    cv2.imwrite(os.path.join(output_dir, output_filename), merged_image)

print("Image merging completed.")
  1. Adjust the input_dir and output_dir variables in the script to match the paths of your input and output directories, respectively.
  2. Save the script and run it using the following command in your terminal:
python image_merge.py

The script provided automatically merges images in stacks of three, saving the merged images with a "merged_" prefix and a stack index in the output directory. Input images should be named to ensure correct alphanumeric sorting. The script supports JPEG format by default but can be modified for other formats.

This will help you. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines