Copy link to clipboard
Copied
Hi,
New to scripting.
2 folders with 160 images in each.
Images will be jpeg's.
Folder 1 Images are named ... 'take_001_cam_001' ... to ... 'take _001_cam_160'
Folder 2 images named take ...'take_002_cam_001' ... to ... 'take _002_cam_160'
I want to take the first image from each folder and place as 2 x layers, do a 50% opacity (possibly input the value as an input variable) on the top layer and save the image to a new folder.
The naming of new files in the new folder could be 'proc_cam_001' to 'proc_001_cam_160'
Repeat with the second image from each folder and continue until end, that is 160 images in the new folder.
Make sense? Thanks in advance:)
This script should do what you are looking for...
/*
Combine and Average Images from 2 Input Folders to Output Folder.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-script/td-p/12700356
Stephen Marsh, v1.0 - 23rd January 2021
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// Input folder 1
var folder1 = Folder.selectDialog("Select the first folder:");
if (folder1 ===
...
Copy link to clipboard
Copied
As a start, you can find existing scripts to do most of what you want:
Copy link to clipboard
Copied
This script should do what you are looking for...
/*
Combine and Average Images from 2 Input Folders to Output Folder.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-script/td-p/12700356
Stephen Marsh, v1.0 - 23rd January 2021
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// Input folder 1
var folder1 = Folder.selectDialog("Select the first folder:");
if (folder1 === null) {
alert('Script cancelled!');
return;
}
// Input folder 2
var folder2 = Folder.selectDialog("Select the second folder to layer:");
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 to jpg/jpeg
var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
var list2 = folder2.getFiles(/\.(jpg|jpeg)$/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("Please select the folder to save to...");
// Save and set the dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// JPEG save options
var jpgOptions = new JPEGSaveOptions();
jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgOptions.embedColorProfile = true;
jpgOptions.matte = MatteType.NONE;
jpgOptions.quality = 12;
// Perform the stacking and saving
for (var i = 0; i < list1.length; i++) {
var doc = open(list1[i]);
var docName = doc.name.replace(/(?:^.+_\d+_)(.+)(?:\.[^\.]+$)/, 'proc_$1');
placeFile(list2[i], 100);
// Change the upper layer to 50% opacity
doc.activeLayer.opacity = 50;
doc.saveAs(new File(saveFolder + '/' + docName + '.jpg'), jpgOptions);
doc.close(SaveOptions.DONOTSAVECHANGES);
}
// End of script
app.displayDialogs = savedDisplayDialogs;
app.beep();
var listCount = list1.length;
alert('Script completed!' + '\r' + listCount + ' JPEG files saved to:' + '\r' + saveFolder.fsName);
} catch (err) {
while (app.documents.length > 0) {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
alert("An unexpected error has occurred!");
}
} else {
alert('Please close all open documents before running this script!');
}
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) {}
}
}());
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
This version uses a simple prompt input to enter in the opacity value rather than using a fixed 50% value:
/*
Combine and Average Images via Prompt from 2 Input Folders to Output Folder.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-script/td-p/12700356
Stephen Marsh, v1.0 - 23rd January 2021
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// Input folder 1
var folder1 = Folder.selectDialog("Select the first folder:");
if (folder1 === null) {
alert('Script cancelled!');
return;
}
// Input folder 2
var folder2 = Folder.selectDialog("Select the second folder to layer:");
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 to jpg/jpeg
var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
var list2 = folder2.getFiles(/\.(jpg|jpeg)$/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("Please select the folder to save to...");
// Prompt input for layer opacity variable
// Loop the input prompt until a number is entered
var lyrOpacity;
while (isNaN(lyrOpacity = prompt("Layer opacity % value:", "50")));
// Test if cancel returns null, then terminate the script
if (lyrOpacity === null) {
alert('Script cancelled!');
return
}
/*
// Test if an empty string is returned, then terminate the script
if (lyrOpacity === "") {
alert('A value was not entered, script cancelled!');
return
}
*/
// Test if an empty string is returned, then repeat
while (lyrOpacity.length === 0) {
lyrOpacity = prompt("Blank value not accepted, please enter the layer opacity % value:", "");
}
// Convert decimal input to integer
var lyrOpacityInteger = parseInt(lyrOpacity);
// Save and set the dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// JPEG save options
var jpgOptions = new JPEGSaveOptions();
jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgOptions.embedColorProfile = true;
jpgOptions.matte = MatteType.NONE;
jpgOptions.quality = 12;
// Perform the stacking and saving
for (var i = 0; i < list1.length; i++) {
var doc = open(list1[i]);
var docName = doc.name.replace(/(?:^.+_\d+_)(.+)(?:\.[^\.]+$)/, 'proc_$1');
placeFile(list2[i], 100);
// Change the upper layer opacity to variable from prompt
doc.activeLayer.opacity = lyrOpacityInteger;
doc.saveAs(new File(saveFolder + '/' + docName + '.jpg'), jpgOptions);
doc.close(SaveOptions.DONOTSAVECHANGES);
}
// End of script
app.displayDialogs = savedDisplayDialogs;
app.beep();
var listCount = list1.length;
alert('Script completed!' + '\r' + listCount + ' JPEG files saved to:' + '\r' + saveFolder.fsName);
} catch (err) {
while (app.documents.length > 0) {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
alert("An unexpected error has occurred!");
}
} else {
alert('Please close all open documents before running this script!');
}
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) {}
}
}());
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
EDIT: Updated code from a private message request, adding a user prompt for a levels midtone/gamma value:
/*
Combine and Average Images via Prompt from 2 Input Folders to Output Folder v1-1.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-script/td-p/12700356
Stephen Marsh, v1.1 - 21st October 2022
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// Input folder 1
var folder1 = Folder.selectDialog("Select the first folder:");
if (folder1 === null) {
alert('Script cancelled!');
return;
}
// Input folder 2
var folder2 = Folder.selectDialog("Select the second folder to layer:");
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 to jpg/jpeg
var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
var list2 = folder2.getFiles(/\.(jpg|jpeg)$/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("Please select the folder to save to...");
// Prompt input for layer opacity variable
// Loop the input prompt until a number is entered
var lyrOpacity;
while (isNaN(lyrOpacity = prompt("Layer opacity % value:", "50")));
// Test if cancel returns null, then terminate the script
if (lyrOpacity === null) {
alert('Script cancelled!');
return
}
/*
// Test if an empty string is returned, then terminate the script
if (lyrOpacity === "") {
alert('A value was not entered, script cancelled!');
return
}
*/
// Test if an empty string is returned, then repeat
while (lyrOpacity.length === 0) {
lyrOpacity = prompt("Blank value not accepted, please enter the layer opacity % value:", "");
}
// Convert decimal input to integer
var lyrOpacityInteger = parseInt(lyrOpacity);
// Prompt input for levels gamma variable
// Loop the input prompt until a number is entered
var gammaValue;
while (isNaN(gammaValue = prompt("Levels Gamma (9.99 - 0.01):", "1.00")));
// Test if cancel returns null, then terminate the script
if (gammaValue === null) {
alert('Script cancelled!');
return
}
// Test if an empty string is returned, then repeat
while (gammaValue.length === 0) {
gammaValue = prompt("Blank value not accepted, please enter the layer opacity % value:", "");
}
// Save and set the dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// JPEG save options
var jpgOptions = new JPEGSaveOptions();
jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgOptions.embedColorProfile = true;
jpgOptions.matte = MatteType.NONE;
jpgOptions.quality = 12;
// Perform the stacking and saving
for (var i = 0; i < list1.length; i++) {
var doc = open(list1[i]);
var docName = doc.name.replace(/(?:^.+_\d+_)(.+)(?:\.[^\.]+$)/, 'proc_$1');
placeFile(list2[i], 100);
// Change the upper layer opacity to variable from prompt
doc.activeLayer.opacity = lyrOpacityInteger;
app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
try {
doc.activeLayer.adjustLevels(0, 255, gammaValue, 0, 255);
} catch (e) {}
doc.saveAs(new File(saveFolder + '/' + docName), jpgOptions);
doc.close(SaveOptions.DONOTSAVECHANGES);
}
// End of script
app.displayDialogs = savedDisplayDialogs;
app.beep();
var listCount = list1.length;
alert('Script completed!' + '\r' + listCount + ' JPEG files saved to:' + '\r' + saveFolder.fsName);
} catch (err) {
while (app.documents.length > 0) {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
alert("An unexpected error has occurred!");
}
} else {
alert('Please close all open documents before running this script!');
}
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
Mr Marsh,
You are a legend!
Thank you so much.
Works just as expected.
Copy link to clipboard
Copied
Your welcome. Thanks for the kind words and feedback.
Copy link to clipboard
Copied
Hi again Stephen,
You were very kind to create a script for me.
Essentially, to open files in a folder and blend togeter.
Would it be difficult for you to 'screen' 2 layers together?
Mark
Copy link to clipboard
Copied
Just changing the upper layer to screen blend mode with no user interaction? What about opacity as in the previous scripts?
Copy link to clipboard
Copied
For now, just aq screen on the top layer:)
No opacity change required.
Copy link to clipboard
Copied
In the first script without the prompt, simply change the following line from:
// Change the upper layer to 50% opacity
doc.activeLayer.opacity = 50;
To:
// Change the upper layer to screen blend mode
doc.activeLayer.blendMode = BlendMode.SCREEN;
Copy link to clipboard
Copied
Top Man - I will try it:)
Copy link to clipboard
Copied
Thanks - works a treat!
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thanks Stephan - works as expected.
You are an amazing fellow to help out inthe way you do.