Skip to main content
Inspiring
January 21, 2019
Answered

Batch replace smart objects v2

  • January 21, 2019
  • 13 replies
  • 34326 views

Greetings,

Unfortunately, my scripting knowledge is very minimal.  In using this script, the script times out and no output files occur.  I am on a pc running Photoshop CC (online subscription, latest update).  It was suggested to me by another forum member to start a new discussion thread here to assist with this problem.

This is what I have:

  •     a mockup file of a canvas wall print with the main single image set as a transformed smart object
  •     a folder of images resized to fit said smart object

This is what I would like a script to do (if possible):

  •     for every image in said folder
  •     replace smart object with images
  •     save each new mockup (one for each new image) as a JPG file.
  •     saved name should be the original image file name (saved in a different directory).  if this naming convention is not possible, its ok as i can rename the files later.

We have over 50k of mockups to do for this particular canvas shape/size....

Any suggestions on how I could streamline this process without having to manually replace and save?  THANK YOU!!!

// replace smart object’s content and save psd;

// 2011, use it at your own risk;

#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;

// psd options;

psdOpts = new PhotoshopSaveOptions();

psdOpts.embedColorProfile = true;

psdOpts.alphaChannels = true;

psdOpts.layers = true;

psdOpts.spotColors = true;

// check if layer is smart object;

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) {

// work through the array;

          for (var m = 0; m < theFiles.length; m++) {

// replace smart object;

                    theLayer = replaceContents (theFiles, theLayer);

                    var theNewName = theFiles.name.match(/(.*)\.[^\.]+$/)[1];

//Raise color picker for Back cover;

try {

app.activeDocument.activeLayer = app.activeDocument.layers[app.activeDocument.layers.length - 1];

// =======================================================

var idsetd = charIDToTypeID( "setd" );

var desc7 = new ActionDescriptor();

var idnull = charIDToTypeID( "null" );

var ref2 = new ActionReference();

var idcontentLayer = stringIDToTypeID( "contentLayer" );

var idOrdn = charIDToTypeID( "Ordn" );

var idTrgt = charIDToTypeID( "Trgt" );

ref2.putEnumerated( idcontentLayer, idOrdn, idTrgt );

desc7.putReference( idnull, ref2 );

var idT = charIDToTypeID( "T   " );

var desc8 = new ActionDescriptor();

var idClr = charIDToTypeID( "Clr " );

var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );

desc7.putObject( idT, idsolidColorLayer, desc8 );

executeAction( idsetd, desc7, DialogModes.ALL );

} catch (e) {};

//save jpg;

                    myDocument.saveAs((new File(thePath+"/"+theName+"_"+theNewName+".psd")),psdOpts,true);

                    }

          }

}

};

////// 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 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

};
This topic has been closed for replies.
Correct answer mpspringer

thank you JJMack​ !!

this script is working great now!  Here is the final working script:

// replace smart object’s content and save psd;

// 2011, use it at your own risk;

#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;

    // psd options;

    psdOpts = new PhotoshopSaveOptions();

    psdOpts.embedColorProfile = true;

    psdOpts.alphaChannels = true;

    psdOpts.layers = true;

    psdOpts.spotColors = true;

    // check if layer is smart object;

    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) {

            // work through the array;

            for (var m = 0; m < theFiles.length; m++) {

                // replace smart object;

                theLayer = replaceContents(theFiles, theLayer);

                var theNewName = theFiles.name.match(/(.*)\.[^\.]+$/)[1];

                //save jpg;

                var jpegOptions = new JPEGSaveOptions();

                jpegOptions.quality = 10;

                jpegOptions.embedColorProfile = true;

                jpegOptions.matte = MatteType.NONE;

                myDocument.saveAs((new File(thePath + "/" + theNewName + ".jpg")), jpegOptions, true);

            }

        }

    }

};

////// 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 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

};

13 replies

Inspiring
January 24, 2019

Found an issue and do not know the solution.

Issue: when selecting more than ~50 image files, the script seems to time out and nothing occurs at all.  very strange.

what could be causing this behavior?

mpspringerAuthorCorrect answer
Inspiring
January 22, 2019

thank you JJMack​ !!

this script is working great now!  Here is the final working script:

// replace smart object’s content and save psd;

// 2011, use it at your own risk;

#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;

    // psd options;

    psdOpts = new PhotoshopSaveOptions();

    psdOpts.embedColorProfile = true;

    psdOpts.alphaChannels = true;

    psdOpts.layers = true;

    psdOpts.spotColors = true;

    // check if layer is smart object;

    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) {

            // work through the array;

            for (var m = 0; m < theFiles.length; m++) {

                // replace smart object;

                theLayer = replaceContents(theFiles, theLayer);

                var theNewName = theFiles.name.match(/(.*)\.[^\.]+$/)[1];

                //save jpg;

                var jpegOptions = new JPEGSaveOptions();

                jpegOptions.quality = 10;

                jpegOptions.embedColorProfile = true;

                jpegOptions.matte = MatteType.NONE;

                myDocument.saveAs((new File(thePath + "/" + theNewName + ".jpg")), jpegOptions, true);

            }

        }

    }

};

////// 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 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

};

JJMack
Community Expert
Community Expert
January 22, 2019

I like that you fixed up the script for yourself you ask for help and made the modification need with the little help provided. Good show thank you...

you may want to change

// replace smart object’s content and save psd;

JJMack
SilverRowan
Participant
August 17, 2020

Hi JJMack,

I wanted to say thank you for your set of scripts, they're amazing

Just to let you know, in the 2020 version of photoshop they throw an error at first, if I comment out line 28 (//@include "PCTpreferences.jsx") they run, but I have NO idea what I just turned off.

As well, the buttons in the dialog box don't actually allow me to browse - is this what I commented out? any idea how to get those to work properly?

The script works, but I have to copy and paste in the file locations and names.
Hopefully this helps anyone else who's getting an error with them.

JJMack
Community Expert
Community Expert
January 22, 2019

How are you running that script.  The script is designed to be run with an  open layered document that you target that is a smart object layer you that want to replace its content.  Once you target that smart object layer you run the script.  The script should open an Open Files dialog for you to select the image files you want to use as replacement images.  The image file types can be PSD, Tif and Jpeg.  The script will then replace the smart object layer object's with the images  and save PSD files not jpeg files in the same folder as the open document you run the script on.  It also try to do  something about a  back cover so the open document must have some other layer that is a back cover.

If you have 50K mockup you would need to open them one at a time target a smart object layer run the script,  select the replacement images files.  You  have a lot of work to do.  You could easily change the script to so all you would need to do is select the folder containing your replacement images and save Jpeg files not PSD file. Still you  would need to open 50K image files one at a time target the smart object layer and select a folder of image files.  

When you want to Process 50,000 mockup files you do not want to need that much human interaction you would want to automate the process of targeting the smart object layer and selecting the folders that contain the proper set of replacement images for each mockup. You would want to batch process your mockup not have to run 50,000 mockup jobs to populate your mockups.   You need to design a mockup template design that can be batch populated.  The develop the batch populating process and script it.

JJMack
Inspiring
January 22, 2019

Thank you for your detailed response.  Please let me clarify what this project entails.

1 PSD Mockup file (layered, with a Smart Object layer)

50k replacement image files

I removed the section of code that contained "the back cover" layer as it was not needed.  After some trial and errors, the script began to work well.

How can the script be modified so it saves the final output as a jpg (not psd)?

// replace smart object’s content and save psd;

// 2011, use it at your own risk;

#

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;

    // psd options;

    psdOpts = new PhotoshopSaveOptions();

    psdOpts.embedColorProfile = true;

    psdOpts.alphaChannels = true;

    psdOpts.layers = true;

    psdOpts.spotColors = true;

    // check if layer is smart object;

    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) {

            // work through the array;

            for (var m = 0; m < theFiles.length; m++) {

                // replace smart object;

                theLayer = replaceContents(theFiles, theLayer);

                var theNewName = theFiles.name.match(/(.*)\.[^\.]+$/)[1];

                //save jpg;

                myDocument.saveAs((new File(thePath + "/" + theName + "_" + theNewName + ".psd")), psdOpts, true);

            }

        }

    }

};

////// 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 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

};

JJMack
Community Expert
Community Expert
May 24, 2020

 

Ah I see, I dint understand the difference between them at first.

 

I can't get these ones to work though, please see screen shots for the error messages. Just to let you know that the folders stated missing are not missing. I have deleted them and created new ones but not working at all. 


To be able to populate more than one smart object layer and keep the script simple. I needed a  design the that you would be able to have a collection of replacement for each smart object layer on the top of the layers stack. To keep the scripts dialog basically the same the folder  for the replacement images was change to a collection of sub folder with a particular name. obj0, obj1, obj2,... obj n,  Where image in obj0 would be  populated into the topmost smart object layer,  obj1 the next smart object layer down etc.  The output Mockup file names is still composed from File name in obj0,  Also all the obj sub folder need to have exactly the same number of replacement images. If you are batching multiple templates the templates need not all have the same number of smart object layers to be replaced.   However, the collection of replacement  images  must have the number of obj(n) folder for the template with the most smart object layers that need to be populated. This is in the documentation. Its brief for I can not type.  The image are process in file name sort order.  The replacement image need to sore in the order you want .     I leading sequence number can the added so image will be populate correctly  otherwise the population will be random.

 

The message you are getting shows you did not create the collection of sub folders.   If you are populating only one smart object layer theere still  needs to be an obj0 sub folder for populating the top most smart object layer.

 

 

To script Photoshop you need to develop some programming skills, know how Photoshop works well and be able Design process for automating what you want done.  You need to have a well thought out design before you start coding.  You need to design for all things that can possibility happen  or your script will have too many restriction, dependencies and bugs. 

JJMack