Skip to main content
Known Participant
April 7, 2024
Answered

Batch replace smart objects layers using a script

  • April 7, 2024
  • 1 reply
  • 6686 views

Hi,

 

If possible, I'm looking for a script to update smart object layers with other image files through a batch process. I work with a file template that has a certain layout that I like in terms of where and how the layers are placed. Whenever I work on a new project, I need to replace the placed images with new images from the new project. I'm looking for a way to streamline my process by automating this. I have next to no knowledge in creating scripts. I only have basic knowledge in putting them to use, so any suggestions would be really helpful. 

Typically I work with files that have between 12 and 20 smart object layers that I need to be able to replace or place a different image file within them. I'm not fussed if the image files are placed via embedding or linking. Ideally I want to be able to start the script, choose a folder from where to pull the image files and fill the 12 to 20 smart object layers individually with the 12 to 20 image files from the chosen folder. 

 

Correct answer c.pfaffenbichler

There is an attachment limit so I've attached what I can. 


// replace smart objects by selected files;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var theSmartObjects = collectSmartObjects();
var theFiles = selectFile (true);
if (theFiles) {
for (var m = 0; m < Math.min(theSmartObjects.length, theFiles.length); m++) {
selectLayerByID(theSmartObjects[m][1], false);
replaceContents (theFiles[m])
}
};
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjects () {
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
    var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
    var theFileRef = soDesc.getString(stringIDToTypeID('fileReference'));
    var theDocID = soDesc.getString(stringIDToTypeID('documentID'));
    var isLinked = soDesc.getBoolean(stringIDToTypeID('linked'));
    if (isLinked == true) {
    var isMissing = soDesc.getBoolean(stringIDToTypeID('linkMissing'));
    var isChanged = soDesc.getBoolean(stringIDToTypeID('linkChanged'));
    var thePath = soDesc.getPath(stringIDToTypeID('link'));
    } else {
    var isMissing = undefined;
    var isChanged = undefined;
    var thePath = undefined
    };
    /*var x = soDesc.getList(stringIDToTypeID("compsList"));
    var theCompsList = soDesc.getObjectValue(stringIDToTypeID("compsList"));
    if (theCompsList.count > 2) {
        var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
        var theSOComps = new Array;
        for (var n = 0; n < theCompsList.count; n++) {
        var thisOne = theCompsList.getObjectValue(n);
        var compName = thisOne.getString(stringIDToTypeID("name"));
        var compID = thisOne.getInteger(stringIDToTypeID("ID"));
        var theComment = thisOne.getString(stringIDToTypeID("comment"));
        theSOComps.push([compName, compID, theComment]);
        };
        theLayers.push([theName, theID, theFileRef, theDocID])
        theLayers.push([theName, theID, theFileRef, theDocID, theSOComps])
    };*/
    theLayers.push([theName, theID, isLinked, isMissing, isChanged, thePath, theID, theFileRef, theDocID])
}
}
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
    ref.putIdentifier(charIDToTypeID("Lyr "), id);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
       if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
      desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
   try{
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};
////// select file //////
function selectFile (multi) {
if (multi == true) {var theString = "please select files"}
else {var theString = "please select one file"};
if ($.os.search(/windows/i) != -1) {var theFiles = File.openDialog (theString, '*.jpg;*.tif;*.psd;*.png', multi)}
else {var theFiles = File.openDialog (theString, getFiles, multi)};
////// filter files  for mac //////
function getFiles (theFile) {
if (theFile.name.match(/\.(jpg|tif|psd|png)$/i) || theFile.constructor.name == "Folder") {
return true
};
};
return theFiles
};
////// replace SmartObject contents //////
function replaceContents (newFile) {
var desc3 = new ActionDescriptor();
desc3.putPath(charIDToTypeID("null"), new File(newFile));
desc3.putInteger(charIDToTypeID("PgNm"), 1);
executeAction(stringIDToTypeID("placedLayerReplaceContents"), desc3, DialogModes.NO);
};

1 reply

c.pfaffenbichler
Community Expert
Community Expert
April 7, 2024

Template Smart Object replacements have come up many times, did you do a Forum search? 

 

How are the replacement images for each of the Smart Objects identifyable? 

Please provide sample images or at the very least meaningful screenshots (including th epertinent Panels) to clarify the naming and file-structure. 

 

jhannelAuthor
Known Participant
April 7, 2024

I've had a look through the forum

and some post were in the general field of what I'm looking for but since I don't know script they are too far off base for me to adapt to what I need. I save my files like this: myname_projectname_itemname_1. The folders are named in a similar way. The images are all 12x12 inches (3600pix by 3600 pix).

 

In this particular example the template has 14 smart object layers so each smart object shape layer is cropped (by width) to evenly distribute these 14 smart object shape layers across the width of the canvas (it gives the effect of paper strips). 

c.pfaffenbichler
Community Expert
Community Expert
April 7, 2024

Could you please provide sample files (the template and a set of replacement images)?