So I figured out how to answer my own question using Photoshop scripting using Javascript. I thought it would be a good idea to share my solution for others to use it, if they would like, or improve it if they have suggestions!
Result
N distinct versions of the same template image with a nice perspective warp on the content image, each exported with a distinct name.
Prerequisites
The only thing you really need is a Photoshop document with at least a smart object/layer named "content". The smart layer itself should contain only one layer; the image you wish to replace. (The script is hardcoded to look for the layer named "content", so you're free to change this name to something else if you wish, just remember to both change the name in you document as well as in the script!)
I have also created two folders. One with input images stored as .jpg, and another one to store output images from the script once they are processed. In my example case, the input folder contains images of some cats.
Description of the script
The steps in my script are the following:
- Select the input and output folders
- Create an array of filenames out of all the jpg files in the input
directory
- In the main template PSD file, find (by layer name) the smart layer called 'content'
- Open the 'content' layer/smartobject
- Open the first replacement file from the array of filenames to be inserted into the smart object
- Duplicate the contents from the replacement file into the smart object
- Close the replacement file. Save the smart object. Close the smart object.
- Export the main template with the image replaced to a jpg in the output folder with the name "{templateName}_{replacementFileName}.jpg"
- Move on to the next file in the loop
You could probably optimize this a bit more, but processing a single image only takes about 2 seconds or so, so I'm already quite pleased.
Script
var extension = '.jpg'
// Function that saves a JPEG of the current active document with the name '{name}.jpg'
function saveJpeg(path, templateName, fileName){
var file = new File(path + '/' + templateName + '_' + fileName + '.jpg')
var opts = new JPEGSaveOptions();
opts.quality = 10;
templateDocument.saveAs(file, opts, true)
}
var templateDocument = app.activeDocument
var templateName = templateDocument.name.replace('.psd', '')
// From a selected folder, store the filenames of all JPG images in an array so we can loop over them later on
var inFolder = Folder(app.activeDocument.path).selectDlg("Please select folder of images to process");
if (inFolder != null)
{
var fileList = inFolder.getFiles('*' + extension);
}
// Select a folder to store all the output images
var outFolder = Folder(app.activeDocument.path).selectDlg("Please select folder to export processed images");
// Loop over all the images that need to be processed, and store each result in '{outFolder}/{templateName}_{fileList[i]}.jpg'
for(var i = 0; i < fileList.length; i++){
// Inside the template document, look for the smart layer called 'content'. Open the smart layer so it can be edited
var contentLayer = templateDocument.layers.getByName('content')
app.activeDocument.activeLayer = contentLayer;
executeAction(stringIDToTypeID("placedLayerEditContents"));
// Create a variable to store the environment of the smart layer
var smartObject = app.activeDocument
// Open the file fileList[i] in a new windows, duplicate it to the smart layer
var openedFile = open(fileList[i]);
var imageSource = app.activeDocument
imageSource.artLayers[0].duplicate(smartObject);
// Get the name from the image so we can use it in our export filename, and close fileList[i] again (without saving etc)
var imageSourceName = imageSource.name.replace(extension, '')
imageSource.close();
// Remove the previously applied image at the bottom of the stack of layers inside the smart layer, to prevent it from accumulating more and more images
smartObject.artLayers[1].remove()
// Save and close the smart layer
smartObject.save();
smartObject.close();
// Export a jpg from the original template document with our newly replaced layer
saveJpeg(outFolder, templateName, imageSourceName)
}
And that's about it! If you like the script feel free to upvote, and if you have suggestions for improvements they would be more than welcome!