Skip to content

Instantly share code, notes, and snippets.

@laryn
Last active October 14, 2025 14:28
Show Gist options
  • Save laryn/0a1f6bf0dab5b713395a835f9bfa805c to your computer and use it in GitHub Desktop.
Save laryn/0a1f6bf0dab5b713395a835f9bfa805c to your computer and use it in GitHub Desktop.
Photoshop script to replace a smart object within a PSD with selected image(s) and save result as a JPG. (Transformations to the smart object will be applied to new images).
// Replace SmartObject’s Content and Save as JPG
// 2017, use it at your own risk
// Via @Circle B: https://graphicdesign.stackexchange.com/questions/92796/replacing-a-smart-object-in-bulk-with-photoshops-variable-data-or-scripts/93359
// JPG code from here: https://forums.adobe.com/thread/737789
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = myDocument.path;
var theLayer = myDocument.activeLayer;
// JPG Options;
jpgSaveOptions = new JPEGSaveOptions();
jpgSaveOptions.embedColorProfile = true;
jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgSaveOptions.matte = MatteType.NONE;
jpgSaveOptions.quality = 8;
// Check if layer is SmartObject;
if (theLayer.kind != "LayerKind.SMARTOBJECT") {
alert("selected layer is not a smart object")
} else {
// Select Files;
if ($.os.search(/windows/i) != -1) {
var theFiles = File.openDialog("please select files", "*.psd;*.tif;*.jpg", true)
} else {
var theFiles = File.openDialog("please select files", getFiles, true)
};
if (theFiles) {
for (var m = 0; m < theFiles.length; m++) {
// Replace SmartObject
theLayer = replaceContents(theFiles[m], theLayer);
var theNewName = theFiles[m].name.match(/(.*)\.[^\.]+$/)[1];
// Save JPG. If you have need of saving different artboards into separate files,
// see https://gist.github.com/laryn/0a1f6bf0dab5b713395a835f9bfa805c#gistcomment-3996733
myDocument.saveAs((new File(thePath + "/" + theName + "_" + theNewName + ".jpg")), jpgSaveOptions, true,Extension.LOWERCASE);
}
}
}
};
// Get PSDs, TIFs and JPGs from files
function getFiles(theFile) {
if (theFile.name.match(/\.(psd|tif|jpg)$/i) != null || theFile.constructor.name == "Folder") {
return true
};
};
// Replace SmartObject Contents
function replaceContents(newFile, theSO) {
app.activeDocument.activeLayer = theSO;
// =======================================================
var idplacedLayerReplaceContents = stringIDToTypeID("placedLayerReplaceContents");
var desc3 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
desc3.putPath(idnull, new File(newFile));
var idPgNm = charIDToTypeID("PgNm");
desc3.putInteger(idPgNm, 1);
executeAction(idplacedLayerReplaceContents, desc3, DialogModes.NO);
return app.activeDocument.activeLayer
};
@stephenjwatkins
Copy link

For my use cases, while the scripts above were resizing images, they were not always applying transformations properly.

I was able to get the results I wanted using "Place Embedded".

In case it may help someone else, here's my code:
https://gist.github.com/stephenjwatkins/41a2547d4a249527692550bc4096afd6

@schroef
Copy link

schroef commented Jul 21, 2025

@stephenjwatkins
Nice edit. I do have a version which allow to choose between 2 methods. It also has a version which open the linked Smart object and then places the file. This method is slower. But I believe it's the same as your version

@schroef
Copy link

schroef commented Aug 8, 2025

@petergambos

Sorry for the late reply. I looked at your file. The reason it throws that error, is because this script can only replace when its a linked smartObject. I have been working on another version, the one i showed earlier with the GUI dialog. That one can also edit, meaning it opens the smartObject and places your file inside. Currently i only have jpg and webp implemented properly.

I tested your file yesterday and noticed the original version i made, v4, does throw this error. When i tested it using edit smartObject, it does work.

I can give the script as is, i didnt touch it for a couple months. Was working on some other scripts.

let me know

@kakachiex2
Copy link

@schroef
I'm working on a similar script Mockup Genetic but will be pay and it's a tool collection and include a customizable toolbar with icon button to run any script UXP Script .psjs, .js, .jsx, .jsxbin
Screenshot 2025-10-12 164240
Screenshot 2025-10-12 164111

@schroef
Copy link

schroef commented Oct 14, 2025

@kakachiex2

Wow that looks really great! I have not expanded my knowledge into uxp yet. Have looked at it a couple times. A new language always seems very daunting. Plus it was still lacking many features back then. Is everything possible now like with jsx and in terms of executing app commands as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment