Skip to main content
Inspiring
January 21, 2019
Answered

Batch replace smart objects v2

  • January 21, 2019
  • 13 replies
  • 34260 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
January 22, 2019

Change the  psd save options section to a save jpeg options  section and change the save statement to save as jpeg file with the jpeg  filename not psd  and use save option you changed the psd save options to.  You will still need to navigate to the replacement images folder and select all the files.

JJMack