• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Batch replace smart objects with existing script

New Here ,
Jan 27, 2023 Jan 27, 2023

Copy link to clipboard

Copied

Hello hello! 

 

I have a great script that I've been using that replaces smart objects and exports the results as jpegs but would like to be able to use it without the two dialogue boxes to automate the process further. The first box comes up to select the image folder to pull content from and the second is to select where to leave the exports.

 

Question: 

Is there any way to do this so that I insert the location of the folder into the script itself and bypass the folder selection? I've been using other examples in forums to replace parts of the script but nothing is working. 

 

The script also doesn't work if the smart object is inside a folder - is this avoidable, as it would be helpful to use it in a document with artboards? 

 

Thank you for your help!

_____________________________________________________________

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('DataMerge-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)
}

 

TOPICS
Actions and scripting , Windows

Views

962

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 27, 2023 Jan 27, 2023

@lipslikemorphinee wrote:

Question: 

Is there any way to do this so that I insert the location of the folder into the script itself and bypass the folder selection? I've been using other examples in forums to replace parts of the script but nothing is working. 


 

 

It depends on the location of the folders and whether they currently exist. Currently, the script is looking at the location where the active doc is located. I'll use the Desktop as an example, you may need to provide more specific i

...

Votes

Translate

Translate
Adobe
Community Expert ,
Jan 27, 2023 Jan 27, 2023

Copy link to clipboard

Copied


@lipslikemorphinee wrote:

Question: 

Is there any way to do this so that I insert the location of the folder into the script itself and bypass the folder selection? I've been using other examples in forums to replace parts of the script but nothing is working. 


 

 

It depends on the location of the folders and whether they currently exist. Currently, the script is looking at the location where the active doc is located. I'll use the Desktop as an example, you may need to provide more specific info if you can't adapt the code.

 

For the input folder, change:

 

var inFolder = Folder(app.activeDocument.path).selectDlg("Please select folder of images to process");

 

To:

 

var inFolder = Folder("~/Desktop/In Folder");

 

Same for the output folder, change:

 

var outFolder = Folder(app.activeDocument.path).selectDlg("Please select folder to export processed images");

 

To:

 

var outFolder = Folder("~/Desktop/Out Folder");

 

If your directory path is absolute, rather than the relative user "~", please provide an example (Mac or Windows).

 

Rather than using a string, you could use the inFolder variable for the output location, or create a new sub-folder in the input folder etc.

 

You can of course add further code to check if the input folder exists and whether it has content in it, or to automatically create the output folder if it doesn't exist.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 31, 2023 Jan 31, 2023

Copy link to clipboard

Copied

Thank you so, so much! 

 

I tried the link you posted but this fix works perfectly. I made an action with the new script and then used it in batch with my exported artboards and it just cycles right through while I get on with other things. 

 

I just want to say thank you, sometimes I forget how selfless and kind other humans can be to each other. I'm really grateful for your help and for unintentionally making me feel better about other people. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 31, 2023 Jan 31, 2023

Copy link to clipboard

Copied

LATEST

You're welcome. Thank you for the kind reply. It is a pleasant change from the common ghost users who never bothered to reply or close off a topic by marking correct answers.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 27, 2023 Jan 27, 2023

Copy link to clipboard

Copied

quote

The script also doesn't work if the smart object is inside a folder - is this avoidable, as it would be helpful to use it in a document with artboards? 

By @lipslikemorphinee

 

 

Does the group/artboard have a consistent name? Or does it have a consistent position in the layer stack?

 

For example, if the Artboard was named "Artboard 1", then change:

 

var contentLayer = templateDocument.layers.getByName('DataMerge-Content')

 

To:

 

var contentLayer = templateDocument.layerSets["Artboard 1"].layers["DataMerge-Content"];

 

 

If the artboard name wasn't consistent, however, it was always the first/top artboard at the head of the layers panel, then you could select the artboard by its index number:

 

var contentLayer = templateDocument.layerSets[0].layers["DataMerge-Content"];

 

Finally, if neither the name nor position of the artboard was consistent, then you could loop over all layers/sets to get to the smart object replacement layer:

 

selectReplacementSO(activeDocument.layers);

function selectReplacementSO(layers) {
    for (var i = 0; i < layers.length; i++) {
        var theLayer = layers[i];
        if (theLayer.typename === "LayerSet") {
            selectReplacementSO(theLayer.layers);
        } else {
            if (theLayer.kind === LayerKind.SMARTOBJECT && theLayer.name === "DataMerge-Content") {
                activeDocument.activeLayer = theLayer;
            }
        }
    }
}

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 27, 2023 Jan 27, 2023

Copy link to clipboard

Copied

The following script simply requires the smart object layer to be selected as the active layer, it doesn't matter if it is in a group/artboard:

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-for-phone-case-mockup/td-p/106...

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines