Copy link to clipboard
Copied
@vnTriNguyen ā There was a very basic error in my previous script, the canvas size was updating using the first doc size, when it should have been looping over each new doc size and adding that. I didn't spot this error as my test files were all square and the same height.
Please try this new 1.2 update, I have tested it and it works as you require:
/*
Vertical Stacker.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-help-export-merge-many-picture-into-one/td-p/1301
...
Copy link to clipboard
Copied
You can try the "Files to Vertically Stacked Layers.jsx" script that I wrote for the following discussion:
Copy link to clipboard
Copied
Thank you your reply, but your script make this image
ā
Copy link to clipboard
Copied
ā
Copy link to clipboard
Copied
You are indeed correct, I built the script using square images, however, I never tried it with varying height images. I'll need to rework the code...
Copy link to clipboard
Copied
@vnTriNguyen ā So how did the revised 1.2 code posted in this topic work for you?
Copy link to clipboard
Copied
thank you @Stephen Marsh , it works great ā¤ļø
Copy link to clipboard
Copied
@vnTriNguyen ā There was a very basic error in my previous script, the canvas size was updating using the first doc size, when it should have been looping over each new doc size and adding that. I didn't spot this error as my test files were all square and the same height.
Please try this new 1.2 update, I have tested it and it works as you require:
/*
Vertical Stacker.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-help-export-merge-many-picture-into-one/td-p/13016395
How to create one big PNG image from multiple PNG images?
Stephen Marsh
v1.2, 20th June 2022
*/
#target photoshop
if (app.documents.length === 0) {
(function () {
// Save the current dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Capture the original ruler units and set the ruler units to pixels
var origUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Select the input folder
var inputFolder = Folder.selectDialog('Please select the input folder:');
// Test if Cancel button returns null, then do nothing
if (inputFolder === null) {
app.beep();
return;
}
// Supported file formats
var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb)$/i);
// Alpha numeric sort
// inputFiles.sort().reverse;
inputFiles.sort();
// Process the first "base" file
var firstFile = app.open(File(inputFiles[0]));
var firstFileName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
app.activeDocument.duplicate("Final", false);
firstFile.close(SaveOptions.DONOTSAVECHANGES);
var docStack = app.documents[0];
app.activeDocument = docStack;
docStack.activeLayer.name = firstFileName;
// Convert layer to smart object
//var idnewPlacedLayer = stringIDToTypeID("newPlacedLayer");
//executeAction( idnewPlacedLayer, undefined, DialogModes.NO );
// Process the remaining file layers to the "base" file
for (var i = 1; i < inputFiles.length; i++) {
var remainingFiles = app.open(File(inputFiles[i]));
var fileName = remainingFiles.name.replace(/\.[^\.]+$/, '');
var aggregateHeight = activeDocument.height.value;
remainingFiles.activeLayer.name = fileName;
remainingFiles.layers[0].duplicate(docStack, ElementPlacement.PLACEATBEGINNING);
remainingFiles.close(SaveOptions.DONOTSAVECHANGES);
relativeCanvasSize(true, aggregateHeight);
align2SelectAll('AdCH');
align2SelectAll('AdBt');
// Convert layer to smart object
//var idnewPlacedLayer = stringIDToTypeID("newPlacedLayer");
//executeAction( idnewPlacedLayer, undefined, DialogModes.NO );
}
app.runMenuItem(stringIDToTypeID("selectAllLayers"));
//reverseLayerStack();
//app.activeDocument.flatten();
app.beep();
alert(inputFiles.length + ' files vertically stacked!');
// Restore the dialogs
app.displayDialogs = savedDisplayDialogs;
// Return the original ruler units
app.preferences.rulerUnits = origUnits;
// Functions
function relativeCanvasSize(relative, height) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putBoolean(s2t("relative"), relative);
descriptor.putUnitDouble(s2t("height"), s2t("pixelsUnit"), height);
descriptor.putEnumerated(s2t("vertical"), s2t("verticalLocation"), s2t("top"));
executeAction(s2t("canvasSize"), descriptor, DialogModes.NO);
}
function align2SelectAll(method) {
app.activeDocument.selection.selectAll();
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
try {
executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
} catch (e) { }
app.activeDocument.selection.deselect();
}
function reverseLayerStack() {
var idreverse = stringIDToTypeID("reverse");
var desc4653 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref2335 = new ActionReference();
var idlayer = stringIDToTypeID("layer");
var idordinal = stringIDToTypeID("ordinal");
var idtargetEnum = stringIDToTypeID("targetEnum");
ref2335.putEnumerated(idlayer, idordinal, idtargetEnum);
desc4653.putReference(idnull, ref2335);
executeAction(idreverse, desc4653, DialogModes.NO);
}
})();
} else {
alert('Please close all open files before running this script...');
}
Note: This code doesn't use smart objects. It is easy enough to "cheat" and add code to create a smart object for each layer, however, that is not the same as placing the original files to create a smart object layer. This may or may not be a critical difference for you.
Copy link to clipboard
Copied
Hi! I was wondering if you had any ideas for how can I merge PSDs that each have multiple layers, I'm talking 30. I guess the process for the first file stays as is, but then how can I copy the layers from the second and third file to the final merged file?
Copy link to clipboard
Copied
Hi! I was wondering if you had any ideas for how can I merge PSDs that each have multiple layers, I'm talking 30. I guess the process for the first file stays as is, but then how can I copy the layers from the second and third file to the final merged file?
By @Damaris38057867y8ru
It would depend on whether you wish to retain the layers or retain and group the layers or flatten or merge visible or select all layers and create a smart object for the base doc and stacked docs.
Copy link to clipboard
Copied
Thank you so much for responding. Here's a bit more detail about what I'm trying to do:
I have multiple product information pages that I'd like to consolidate into a single document. Each product currently has between 2 to 4 different pages, and I want to combine them to better manage and organize this information. The width of all pages is consistent at around 1000 pixels, though the length varies.
In the product information pages I have elements such as product images, text descriptions, usage instructions, and so on. My goal is to merge these pages while keeping the final psd editable. This means I need the text to remain editable for potential translation into other languages, and I want to be able to change the images if necessary.
Thanks again^^
Copy link to clipboard
Copied
Thank you so much for responding. Here's a bit more detail about what I'm trying to do:
I have multiple product information pages that I'd like to consolidate into a single document. Each product currently has between 2 to 4 different pages, and I want to combine them to better manage and organize this information.
...
My goal is to merge these pages while keeping the final psd editable. This means I need the text to remain editable for potential translation into other languages, and I want to be able to change the images if necessary.
By @Damaris38057867y8ru
Will you select multiple, specific documents from a folder containing many files... Or will you simply be processing all files in a folder? How are the files named? In what order will the files need to be combined? How would the combined file be named?
It would be best to provide say 3 samples of the original "before" files and 1 final example "after" combined file.
Copy link to clipboard
Copied
Thank you so much for this! Can I ask if it is possible ot make it so that it is a different photoshop file let's say, every 4 images? Or am I better off just doing this multiple times with 4 images at a time? Let's say I have 144 images and I want them to merge every 4 images into 1 separate psd file for a total of 36 psds, is it possible for me to modify the code to make it work that way? Or is this impossible in PS. If not, I can always just run the script manually multiple times, it will still be helpful to me. Thank you!
Copy link to clipboard
Copied
I realized it is only selectable by folder, which means I would have to separate every 4 photos into a different folder. Is there another option to use aside from Folder.selectDialog that lets me manually select photos instead? Thank you!
Copy link to clipboard
Copied
Super sorry for the spam. I'm not able to edit my comments yet. I've been able to achieve this just now by modifying the script to use File.openDialog with multiSelect enabled instead, and just set var inputFiles = inputFolder;
// Select the input folder
var inputFolder = File.openDialog('Please select the photos:', true);
Would the first question I have still be possible about doing it every 4 or [x] number of files? I understand I would have to learn more about the documentation of JS as I'm not familiar enough yet.
Copy link to clipboard
Copied
I realized it is only selectable by folder, which means I would have to separate every 4 photos into a different folder. Is there another option to use aside from Folder.selectDialog that lets me manually select photos instead? Thank you!
By @Wuqu312
You can take a look at this script, it's for stacking either horizontal or vertical layout and does allow you to select the files manually:
Copy link to clipboard
Copied
Thank you so much for this! Can I ask if it is possible ot make it so that it is a different photoshop file let's say, every 4 images? Or am I better off just doing this multiple times with 4 images at a time? Let's say I have 144 images and I want them to merge every 4 images into 1 separate psd file for a total of 36 psds, is it possible for me to modify the code to make it work that way? Or is this impossible in PS. If not, I can always just run the script manually multiple times, it will still be helpful to me. Thank you!
By @Wuqu312
The following script will vertically stack all supported image formats from the selected folder into sets of 4, saving as PNG:
/*
Vertical Stacker to Sets of 4.jsx
Stephen Marsh
v1.0, 2nd April 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-help-export-merge-many-picture-into-one/td-p/13016395
*/
#target photoshop
if (app.documents.length === 0) {
(function () {
// Save the current dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Capture the original ruler units and set the ruler units to pixels
var origUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// Select the input folder
var inputFolder = Folder.selectDialog('Please select the input folder:');
// Test if Cancel button returns null, then do nothing
if (inputFolder === null) {
app.beep();
return;
}
// Supported file formats
var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb)$/i);
// Alpha numeric sort
inputFiles.sort();
// Process files in batches of 4
for (var batchStart = 0; batchStart < inputFiles.length; batchStart += 4) {
var batchEnd = Math.min(batchStart + 4, inputFiles.length);
var batchFiles = inputFiles.slice(batchStart, batchEnd);
// Process the first "base" file in the batch
var firstFile = app.open(File(batchFiles[0]));
var firstFileName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
app.activeDocument.duplicate("Final_" + (batchStart / 4 + 1), false);
firstFile.close(SaveOptions.DONOTSAVECHANGES);
var docStack = app.documents[0];
app.activeDocument = docStack;
docStack.activeLayer.name = firstFileName;
// Process the remaining file layers in the batch
for (var i = 1; i < batchFiles.length; i++) {
var remainingFiles = app.open(File(batchFiles[i]));
var fileName = remainingFiles.name.replace(/\.[^\.]+$/, '');
var aggregateHeight = activeDocument.height.value;
remainingFiles.activeLayer.name = fileName;
remainingFiles.layers[0].duplicate(docStack, ElementPlacement.PLACEATBEGINNING);
remainingFiles.close(SaveOptions.DONOTSAVECHANGES);
relativeCanvasSize(true, aggregateHeight);
align2SelectAll('AdCH');
align2SelectAll('AdBt');
}
// Save the final stacked image for the batch
var saveFile = new File(inputFolder + "/stacked_" + (batchStart / 4 + 1) + ".png");
var options = new PNGSaveOptions();
docStack.saveAs(saveFile, options, true, Extension.LOWERCASE);
docStack.close(SaveOptions.DONOTSAVECHANGES);
}
app.beep();
alert(inputFiles.length + ' files processed and saved in batches of 4!');
// Restore the dialogs
app.displayDialogs = savedDisplayDialogs;
// Return the original ruler units
app.preferences.rulerUnits = origUnits;
// Functions
function relativeCanvasSize(relative, height) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putBoolean(s2t("relative"), relative);
descriptor.putUnitDouble(s2t("height"), s2t("pixelsUnit"), height);
descriptor.putEnumerated(s2t("vertical"), s2t("verticalLocation"), s2t("top"));
executeAction(s2t("canvasSize"), descriptor, DialogModes.NO);
}
function align2SelectAll(method) {
app.activeDocument.selection.selectAll();
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
desc.putReference(charIDToTypeID("null"), ref);
desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
try {
executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
} catch (e) { }
app.activeDocument.selection.deselect();
}
})();
} else {
alert('Please close all open files before running this script...');
}
I also have some generic scripts which will stack layers to variable, user-defined sets, however, they just stack layers without adjusting the canvas or position of the layers:
Find more inspiration, events, and resources on the new Adobe Community
Explore Now