Copy link to clipboard
Copied
Hello, I have two directories with 200 images each. The files are named 001.png, 002.png, ... in both directories. Now I want to load 001.png from Directory A and 001.png from Directory B into photoshop as 2 layers and save it into a third directory as 001.psd. This should be done for all 200 images in both directories.
My question: Is this possible somehow?
Try this modified version:
/*
Combine PNG files from 2 input folders to Layered PSD.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-merge-load-images-from-2-directories-as-layers/td-p/12804714
Stephen Marsh, v1.2 - 24th July 2024
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// PNG image input folder 1
var folder1 = Folder.selectDialog("Select the 1st PNG imag
...
Copy link to clipboard
Copied
Yes this is possible with a script. This question comes up every couple of months on the forum with different variations. I can adapt one of the existing scripts a little later when I have time.
Copy link to clipboard
Copied
Thank you, I took a look at your script from the thread linked by Kukurykus and that's exactly what I was looking for. Tried to adapt it to my scenario but it's still giving me an error. I'm not good at these things so I'll wait for your adapted script!
Again thanks a lot!
Copy link to clipboard
Copied
In the meantime try mine unless you'll have an error with it as well 😉
Copy link to clipboard
Copied
Do you want to do something to the stacked layers? Opacity %, blend mode, mask, action etc?
Copy link to clipboard
Copied
No, nothing.
Copy link to clipboard
Copied
Is the 2nd image transparent?
Copy link to clipboard
Copied
It is not. The images are almost identical. Resolution and dpi are same.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Try this modified version:
/*
Combine PNG files from 2 input folders to Layered PSD.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-merge-load-images-from-2-directories-as-layers/td-p/12804714
Stephen Marsh, v1.2 - 24th July 2024
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// PNG image input folder 1
var folder1 = Folder.selectDialog("Select the 1st PNG image folder:");
if (folder1 === null) {
alert('Script cancelled!');
return;
}
// PNG image input folder 2
var folder2 = Folder.selectDialog("Select the 2nd PNG image folder:");
if (folder2 === null) {
alert('Script cancelled!');
return;
}
// Validate input folder selection
var validateInputDir = (folder1.fsName === folder2.fsName);
if (validateInputDir === true) {
alert("Script cancelled as both the input folders are the same!");
return;
}
// Limit the file input formats
var list1 = folder1.getFiles(/\.(png)$/i);
var list2 = folder2.getFiles(/\.(png)$/i);
// Alpha-numeric sort
list1.sort();
list2.sort();
// Validate that folder 1 & 2 lists are not empty
var validateEmptyList = (list1.length > 0 && list2.length > 0);
if (validateEmptyList === false) {
alert("Script cancelled as one of the input folders is empty!");
return;
}
// Validate that the item count in folder 1 & 2 matches
var validateListLength = (list1.length === list2.length);
if (validateListLength === false) {
alert("Script cancelled as the input folders don't have equal quantities of images!");
return;
}
// Output folder
var saveFolder = Folder.selectDialog("Select the folder to save to...");
// Save and set the dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// PSD save options
var psdSaveOptions = new PhotoshopSaveOptions();
psdSaveOptions.embedColorProfile = true;
psdSaveOptions.alphaChannels = true;
psdSaveOptions.layers = true;
// Perform the stacking and saving
for (var i = 0; i < list1.length; i++) {
var doc = open(list1[i]);
var docName = doc.name.replace(/\.[^\.]+$/, '');
app.activeDocument.activeLayer.name = folder1.displayName;
placeFile(list2[i], 100);
try {
app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
} catch (e) { }
app.activeDocument.activeLayer.name = folder2.displayName;
doc.saveAs(new File(saveFolder + '/' + docName + '.psd'), psdSaveOptions);
doc.close(SaveOptions.DONOTSAVECHANGES);
}
// End of script
app.displayDialogs = savedDisplayDialogs;
app.beep();
var listCount = list1.length;
alert('Script completed!' + '\r' + listCount + ' Layered PSD files saved to:' + '\r' + saveFolder.fsName);
} catch (err) {
while (app.documents.length > 0) {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
alert("An unexpected error has occurred!" + "\r" + e + ' ' + e.line);
}
} else {
alert('Please close all open documents before running this script!');
}
///// FUNCTIONS /////
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) { }
}
}());
Copy link to clipboard
Copied
Yes, this worked splendidly! There's only one small thing I noticed that could be improved on. It seems the layers are named after the png files, so both names are identical. To differentiate between them a little better, would it be possible to have them adopt the name of their origin folders?
Copy link to clipboard
Copied
Yes, that is easy to modify, I have updated the original code to a 1.1 version.
Copy link to clipboard
Copied
Thank you!!
Copy link to clipboard
Copied
Your welcome!
Copy link to clipboard
Copied
Hi Stephen Marsh, thanks for offering this script. I'm on PS 25, Win 10. I run this script, select the folders, the first image is loaded, then I get "An unexpected error has occured". Using alert() in the code, I narrowed the problem to the line below (i.e.everything prior works fine). I tried to recreate the problem manually. I open the first image, place the second image on top. Then under Layer->Rasterize, i see that "Rasterize" is grayed out. Is this the problem? is there another way to "commit" / "place" the "placed" second image?
app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
Copy link to clipboard
Copied
I"ll look into it.
Placing the image should create an embedded smart object.
The rasterize layer step was there a create a standard pixel layer.
Copy link to clipboard
Copied
Thanks for the reply. In PS Preferences, I have "Always place as smart object" checked OFF, so I don't think it's a smar object issue. Placing an image manualy creates a translation box. I solved the problem by sending an "Enter" keystroke (using WScript on Win) right after the second image placement, and commenting "rasterizePlaced".
Copy link to clipboard
Copied
The layer icon should indicate whether it's a smart object.
I didn't consider that the file may not be placed as a smart object. What would have been better is for my script to use a try/catch or a conditional to check whether the layer is a smart object before using the rasterize command.
@Jebadiah25093915zgho – I have just updated the code to a 1.2 version.
Copy link to clipboard
Copied
I have just updated the code to a 1.2 version to convert the %20 characters to the space character for input folders that contain spaces.
To use both the input folder and filename in the layered PSD, change line 75 to:
app.activeDocument.activeLayer.name = folder1.displayName + " - " + docName + ".png";
And line 78 to:
app.activeDocument.activeLayer.name = folder2.displayName + " - " + docName + ".png";
Copy link to clipboard
Copied
Make it for all possible special characters at once an user can have in names than only for one.
Copy link to clipboard
Copied
@Kukurykus wrote:
Make it for all possible special characters at once an user can have in names than only for one.
Thank you, I updated the code shortly after posting, before you message came in...
Does replacing:
folder1.name.replace(/%20/g, ' ');
With:
folder2.displayName;
Successfully achieve that result?
Copy link to clipboard
Copied
I thought of decodeURI, but in this case your solution is even better 😉
Copy link to clipboard
Copied
As you know, I taught myself regex before scripting.
There is a saying that goes something like:
"If you only know how to use a hammer, every screw looks like a nail".
I am often guilty of that, I often use a regex before using something that may be better suited to the task at hand! 🙂
http://regex.info/blog/2006-09-15/247
https://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/