Script to Export Contents of all Smart Objects in a Photoshop file

New Here ,
Oct 01, 2019

Copy link to clipboard

Copied

I am trying to write a script that will batch export all smart objects as files.

 

Like using the menu ->  Layer/SmartObjects/Export Contents... but does it for every Smart Object is the photoshop file.

 

I have written some code that searches all layers and can determine if it is a Smart Object, but I am stuck on how to export the smart objects content as a file.

 

var oldPath = activeDocument.path;

function ExportSmartObject(layerNode) {
for (var i=0; i<layerNode.length; i++) {

ExportSmartObject(layerNode[i].layerSets);

for(var layerIndex=0; layerIndex < layerNode[i].artLayers.length; layerIndex++) {
var layer=layerNode[i].artLayers[layerIndex];
if (layer.kind == "LayerKind.SMARTOBJECT") {
alert("Smart Object Found")

// Export Smart Object Content

}
}
}
}


ExportSmartObject(app.activeDocument.layerSets);

TOPICS
Actions and scripting, How to

Views

1.0K

Likes

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

Script to Export Contents of all Smart Objects in a Photoshop file

New Here ,
Oct 01, 2019

Copy link to clipboard

Copied

I am trying to write a script that will batch export all smart objects as files.

 

Like using the menu ->  Layer/SmartObjects/Export Contents... but does it for every Smart Object is the photoshop file.

 

I have written some code that searches all layers and can determine if it is a Smart Object, but I am stuck on how to export the smart objects content as a file.

 

var oldPath = activeDocument.path;

function ExportSmartObject(layerNode) {
for (var i=0; i<layerNode.length; i++) {

ExportSmartObject(layerNode[i].layerSets);

for(var layerIndex=0; layerIndex < layerNode[i].artLayers.length; layerIndex++) {
var layer=layerNode[i].artLayers[layerIndex];
if (layer.kind == "LayerKind.SMARTOBJECT") {
alert("Smart Object Found")

// Export Smart Object Content

}
}
}
}


ExportSmartObject(app.activeDocument.layerSets);

TOPICS
Actions and scripting, How to

Views

1.0K

Likes

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
Oct 01, 2019 0
Adobe Community Professional ,
Oct 02, 2019

Copy link to clipboard

Copied

 

sTT = stringIDToTypeID; (dsc = new ActionDescriptor())
.putPath(sTT('null'), File('~/desktop/' + i + '.psb'))
executeAction(sTT('placedLayerExportContents'), dsc)

 

Likes

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
Reply
Loading...
Oct 02, 2019 1
Adobe Community Professional ,
Oct 02, 2019

Copy link to clipboard

Copied

Being new to scripting, I would have done it as below... This code is only for the active layer, it would need to be looped/iterated over all layers. Note: There is no error checking for duplicate layer names (therefore the lowest layer in the stack with the same name would be saved).

 

 

 

 

 

#target photoshop
// Save Active Smart Object Layer as PSD
app.displayDialogs = DialogModes.NO; 
var layer = app.activeDocument.activeLayer;
var layerName = app.activeDocument.activeLayer.name;
var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
var savePath = activeDocument.path;
var saveName = File(savePath + "/" + docName + "_" + layerName + "_SmartObjectLayer.psd" );

function SavePSD(saveFile){    
psdSaveOptions = new PhotoshopSaveOptions();    
psdSaveOptions.embedColorProfile = true;    
psdSaveOptions.alphaChannels = true;     
psdSaveOptions.layers = true;     
app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);    
}; 

if (layer.kind == "LayerKind.SMARTOBJECT") {
app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
SavePSD(saveName); 
}
else
{
// Skip any layers that are not Smart Object layers    
}

app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

 

 

 

 

 

 

Likes

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
Reply
Loading...
Oct 02, 2019 0
Adobe Community Professional ,
Oct 04, 2019

Copy link to clipboard

Copied

I can’t believe how hard it is proving to find easily adaptable code examples to loop/iterate over all layers in a file.

 

OK, I managed to graft on some code that works, the issue was ESTK throwing up an error that does not happen when the script is run directly from Photoshop.

Likes

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
Reply
Loading...
Oct 04, 2019 0
Explorer ,
Mar 15, 2020

Copy link to clipboard

Copied

Hi! Many thanks for your work and script. Can you please assist with running it? Im struggling with the same issue here
How can I export contents of all smart objects in .psd file? When I run your script it closes my Photoshop window and nothing happen.

Likes

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
Reply
Loading...
Mar 15, 2020 0
Adobe Community Professional ,
Mar 15, 2020

Copy link to clipboard

Copied

What is the smart object content?

 

Linked or embedded?

 

Raster or vector?

 

Are the SO layers inside a layer group/set?

Likes

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
Reply
Loading...
Mar 15, 2020 0
Adobe Community Professional ,
Mar 15, 2020

Copy link to clipboard

Copied

Thanks for the bump, I just realised that I never updated my previous post with the updated code to loop over all layers:

 

//community.adobe.com/t5/Photoshop/Script-to-Export-Contents-of-all-Smart-Objects-in-a-Photoshop/td-p/10644877
//Script to Export Contents of all Smart Objects in a Photoshop file
// Note: There is no error checking for duplicate layer names (therefore the lowest layer in the stack with the same name would be saved).

#target photoshop  

// Start Loop over all layers
  
var doc = app.activeDocument;  
var layerVisble  
  
doc.activeLayer = doc.layers[0];  
  
for(var i=0;i<doc.layers.length;i++){  
    doc.activeLayer = doc.layers[i];  
    layerVisible = doc.activeLayer.visible;  
    doc.activeLayer.visible = true;  
    run ();  
    doc.activeLayer.visible = layerVisible;  
    }  

// End Loop over all layers

// Start Main Code
function run(){  

app.displayDialogs = DialogModes.NO; 
var layer = app.activeDocument.activeLayer;
var layerName = app.activeDocument.activeLayer.name;
var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
var savePath = activeDocument.path;
var saveName = File(savePath + "/" + docName + "_" + layerName + "_SmartObjectLayer.psd" );

function SavePSD(saveFile){    
psdSaveOptions = new PhotoshopSaveOptions();    
psdSaveOptions.embedColorProfile = true;    
psdSaveOptions.alphaChannels = true;     
psdSaveOptions.layers = true;     
app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);    
}; 

if (layer.kind == "LayerKind.SMARTOBJECT") {
app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
SavePSD(saveName); 
}
else
{
// Skip any layers that are not Smart Object layers    
}

app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

}

// End Main Code

Likes

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
Reply
Loading...
Mar 15, 2020 1
Adobe Community Professional ,
Mar 15, 2020

Copy link to clipboard

Copied

Being new to scripting, my script is very simple... 

 

The main file that holds the SO layers must be saved, there is no error checking in the script for this.

 

If there are layer sets/groups, then the file will close and nothing will be saved – there is no error checking in the script for this.

 

The script simply saves a PSD version of each smart object layer to the original document path. If your main file is on the desktop, then that is where each smart object will be saved. This behaviour is easy to change if desired. The SO files could be saved as a PSD to a folder of your choice via a window to select the save folder. Or the files could be saved to a fixed path/location. Or the files could be saved into a sub-folder in the folder where the main file is currently saved.

 

The saved PSD files will have the following suffix added to the layer name:

 

_SmartObjectLayer.psd

 

As mentioned in the script comments, if you have multiple SO layers with exactly the same name, then only the lowest layer in the layer stack would be saved.

Likes

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
Reply
Loading...
Mar 15, 2020 0
Explorer ,
Mar 15, 2020

Copy link to clipboard

Copied

Many thanks for your work Stephen!

Can you please clarify "If there are layer sets/groups, then the file will close and nothing will be saved – there is no error checking in the script for this."

You mean if I have groups like this?

Screenshot 2020-03-16 at 08.49.46.png

Likes

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
Reply
Loading...
Mar 15, 2020 0
Adobe Community Professional ,
Mar 16, 2020

Copy link to clipboard

Copied

No, layer sets/groups are "folders" that can contain layers or nested folders/layers as in this image:

 

Screen Shot 2020-03-16 at 19.45.53.png

 

The problem was my original code was too simplistic and did not take layer groups/sets into account. I have since updated the code and will repost it shortly.

Likes

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
Reply
Loading...
Mar 16, 2020 0
Adobe Community Professional ,
Mar 16, 2020

Copy link to clipboard

Copied

This updated code will process standard layers and layers inside layer sets or nested layer sets. All of the previous limitations still apply, such as duplicate layer names are not supported.

 

/*
//community.adobe.com/t5/Photoshop/Script-to-Export-Contents-of-all-Smart-Objects-in-a-Photoshop/td-p/10644877

Note: There is no error checking for duplicate layer names (therefore the lowest layer in the stack with the same name would be saved).

Original script revised to include smart objects in layer sets (layer groups)... With special thanks to Christoph Pfaffenbichler for the recursive SO processing framework:
feedback.photoshop.com/photoshop_family/topics/rasterize_all_smart_objects_in_a_psd_file_to_shrink_down_its_size
*/

#target photoshop

var myDocument = app.activeDocument;
myDocument.suspendHistory("processAllSmartObjects", "processSOLayers(myDocument)");

////// Function to process all smart objects ////// 
function processSOLayers(theParent) {
    for (var m = theParent.layers.length - 1; m >= 0; m--) {
        var theLayer = theParent.layers[m];
        
        // apply the funtion to layersets; 
        if (theLayer.typename == "ArtLayer") {
            if (theLayer.kind == LayerKind.SMARTOBJECT) {
                var theVisibility = theLayer.visible;
                myDocument.activeLayer = theLayer;

                // Run the function to save out the layers
                soLayerSaver();

                // Start Main Function
                function soLayerSaver() {

                    app.displayDialogs = DialogModes.NO;
                    var layer = app.activeDocument.activeLayer;
                    var layerName = app.activeDocument.activeLayer.name;
                    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    var savePath = activeDocument.path;
                    var saveName = File(savePath + "/" + docName + "_" + layerName + "_SmartObjectLayer.psd");

                    function SavePSD(saveFile) {
                        psdSaveOptions = new PhotoshopSaveOptions();
                        psdSaveOptions.embedColorProfile = true;
                        psdSaveOptions.alphaChannels = true;
                        psdSaveOptions.layers = true;
                        app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                    };

                    if (layer.kind == "LayerKind.SMARTOBJECT") {
                        app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
                        SavePSD(saveName);
                    } else {
                        // Skip any layers that are not Smart Object layers    
                    }

                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                }

                // Reset visibility; 
                theLayer.visible = theVisibility;
            };
        } else {
            processSOLayers(theLayer)
        }
    }
    return
};

Likes

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
Reply
Loading...
Mar 16, 2020 1
Engaged ,
Jan 02, 2021

Copy link to clipboard

Copied

@Stephen_A_Marsh 

 

I hope you dont mind. I added something parts from "Layer Comps to Files" so when there are layers with the same name it will index those. I added a little timer i found in one of Tom Ruarks script, so i could time the difference. I dint really notice a big impact of the extra check. You can find that check in the beginning of the main function.

 

Below you see layers with the same name get an index, therefor they wont be overwritten. I thought that would be nice

Dupli layer names gets index nowDupli layer names gets index now

 

/*
//community.adobe.com/t5/Photoshop/Script-to-Export-Contents-of-all-Smart-Objects-in-a-Photoshop/td-p/10644877

Note: There is no error checking for duplicate layer names (therefore the lowest layer in the stack with the same name would be saved).

Original script revised to include smart objects in layer sets (layer groups)... With special thanks to Christoph Pfaffenbichler for the recursive SO processing framework:
feedback.photoshop.com/photoshop_family/topics/rasterize_all_smart_objects_in_a_psd_file_to_shrink_down_its_size
*/

#target photoshop

var myDocument = app.activeDocument;
myDocument.suspendHistory("processAllSmartObjects", "processSOLayers(myDocument)");


///////////////////////////////////////////////////////////////////////////////
// Object for timing things in JavaScript
///////////////////////////////////////////////////////////////////////////////
function Timer() {
	// member properties
	this.startTime = new Date();
	this.endTime = new Date();
	
	// member methods
	
	// reset the start time to now
	this.start = function () { this.startTime = new Date(); }
	
	// reset the end time to now
	this.stop = function () { this.endTime = new Date(); }
	
	// get the difference in milliseconds between start and stop
	this.getTime = function () { return (this.endTime.getTime() - this.startTime.getTime()) / 1000; }
	
	// get the current elapsed time from start to now, this sets the endTime
	this.getElapsed = function () { this.endTime = new Date(); return this.getTime(); }
}

// Timer Tom Ruark
// Source: Getter.jsx
var totalTime = new Timer();


///////////////////////////////////////////////////////////////////////////////
// Function: countLayerNames
// Usage:  Count the comps' names collecting duplicates
// Input: collection of comps
// Return: object with names as keys and as values, an object with total count and an index (for incrementing during file naming)
// Source: Layer-Comps-To-Files.jsx
///////////////////////////////////////////////////////////////////////////////
function countLayerNames(list){
    var obj = {};
    for(var i = 0; i<list.length; i++){
        var name = list[i].name;
        if(name in obj){
            obj[name].total += 1;
		} else { 
            obj[name] = {total: 1, nameIndex: 1};
		}
	}
    return obj;
}

////// Function to process all smart objects ////// 
function processSOLayers(theParent) {
    var totalTime = new Timer(); // Tom Ruark > Getter.jsx
    var count = countLayerNames(theParent.layers);
    for (var m = theParent.layers.length - 1; m >= 0; m--) {
        var theLayer = theParent.layers[m];
        
        // apply the funtion to layersets; 
        if (theLayer.typename == "ArtLayer") {
            if (theLayer.kind == LayerKind.SMARTOBJECT) {
                var theVisibility = theLayer.visible;
                myDocument.activeLayer = theLayer;

                // Run the function to save out the layers
                soLayerSaver();

                // Start Main Function
                function soLayerSaver() {

                    app.displayDialogs = DialogModes.NO;
                    var layer = app.activeDocument.activeLayer;
                    var layerName = app.activeDocument.activeLayer.name;
                    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    var savePath = activeDocument.path;
                    
                    // check for dupli names
                    var nameEntry = count[theLayer.name];
                    if(nameEntry.total > 1) { // if > 2 then we add index numbers
                        layerName +=  '_' + nameEntry.nameIndex++;
                    }
                    var saveName = File(savePath + "/" + docName + "_" + layerName + "_SmartObjectLayer.psd");

                    function SavePSD(saveFile) {
                        psdSaveOptions = new PhotoshopSaveOptions();
                        psdSaveOptions.embedColorProfile = true;
                        psdSaveOptions.alphaChannels = true;
                        psdSaveOptions.layers = true;
                        app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                    };

                    if (layer.kind == "LayerKind.SMARTOBJECT") {
                        app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
                        SavePSD(saveName);
                    } else {
                        // Skip any layers that are not Smart Object layers    
                    }

                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                }

                // Reset visibility; 
                theLayer.visible = theVisibility;
            };
        } else {
            processSOLayers(theLayer)
        }
    }
    
    alert("Script Time: " + totalTime.getElapsed())
};

 

 

Likes

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
Reply
Loading...
Jan 02, 2021 1
Adobe Community Professional ,
Jan 03, 2021

Copy link to clipboard

Copied

No, I don't mind if you improve my scripts! Can I notify you whenever I write a script and ask for you to improve it? I am of course (mostly) joking...

 

 

Likes

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
Reply
Loading...
Jan 03, 2021 1
schroef LATEST
Engaged ,
Jan 04, 2021

Copy link to clipboard

Copied

Sure if i get a coffee every time 🙂

Likes

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
Reply
Loading...
Jan 04, 2021 0
Adobe Community Professional ,
Jan 03, 2021

Copy link to clipboard

Copied

I have wrapped the updated script in a try/catch as it would previously silently fail if being run on an unsaved document.

 

 

/*
//community.adobe.com/t5/Photoshop/Script-to-Export-Contents-of-all-Smart-Objects-in-a-Photoshop/td-p/10644877

Original script revised to include smart objects in layer sets (layer groups)... With special thanks to Christoph Pfaffenbichler for the recursive SO processing framework:
feedback.photoshop.com/photoshop_family/topics/rasterize_all_smart_objects_in_a_psd_file_to_shrink_down_its_size

January 3rd 2021: Thanks to schroef for adding handling for duplicate named layers!
*/

#target photoshop

/* Start Open/Saved Document Error Check - Part A: Try */
savedDoc();
function savedDoc() {
  try {
    app.activeDocument.path;
/* Finish Open/Saved Document Error Check - Part A: Try */

/* Main Code Start */
var myDocument = app.activeDocument;
myDocument.suspendHistory("processAllSmartObjects", "processSOLayers(myDocument)");

///////////////////////////////////////////////////////////////////////////////
// Object for timing things in JavaScript
///////////////////////////////////////////////////////////////////////////////
function Timer() {
	// member properties
	this.startTime = new Date();
	this.endTime = new Date();
	
	// member methods
	
	// reset the start time to now
    this.start = function () { this.startTime = new Date() };
	
	// reset the end time to now
    this.stop = function () { this.endTime = new Date() };
	
	// get the difference in milliseconds between start and stop
    this.getTime = function () { return (this.endTime.getTime() - this.startTime.getTime()) / 1000 };
	
	// get the current elapsed time from start to now, this sets the endTime
    this.getElapsed = function () { this.endTime = new Date(); return this.getTime() };
}

// Timer Tom Ruark
// Source: Getter.jsx
var totalTime = new Timer();

///////////////////////////////////////////////////////////////////////////////
// Function: countLayerNames
// Usage:  Count the comps' names collecting duplicates
// Input: collection of comps
// Return: object with names as keys and as values, an object with total count and an index (for incrementing during file naming)
// Source: Layer-Comps-To-Files.jsx
///////////////////////////////////////////////////////////////////////////////
function countLayerNames(list){
    var obj = {};
    for(var i = 0; i<list.length; i++){
        var name = list[i].name;
        if(name in obj){
            obj[name].total += 1;
		} else { 
            obj[name] = {total: 1, nameIndex: 1};
		}
	}
    return obj;
}

////// Function to process all smart objects ////// 
function processSOLayers(theParent) {
    var totalTime = new Timer(); // Tom Ruark > Getter.jsx
    var count = countLayerNames(theParent.layers);
    for (var m = theParent.layers.length - 1; m >= 0; m--) {
        var theLayer = theParent.layers[m];
        
        // apply the funtion to layersets; 
        if (theLayer.typename == "ArtLayer") {
            if (theLayer.kind == LayerKind.SMARTOBJECT) {
                var theVisibility = theLayer.visible;
                myDocument.activeLayer = theLayer;

                // Run the function to save out the layers
                soLayerSaver();

                // Start Main Function
                function soLayerSaver() {

                    app.displayDialogs = DialogModes.NO;
                    var layer = app.activeDocument.activeLayer;
                    var layerName = app.activeDocument.activeLayer.name;
                    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    var savePath = activeDocument.path;
                    
                    // check for dupli names
                    var nameEntry = count[theLayer.name];
                    if(nameEntry.total > 1) { // if > 2 then we add index numbers
                        layerName +=  '_' + nameEntry.nameIndex++;
                    }
                    var saveName = File(savePath + "/" + docName + "_" + layerName + "_SmartObjectLayer.psd");

                    function SavePSD(saveFile) {
                        psdSaveOptions = new PhotoshopSaveOptions();
                        psdSaveOptions.embedColorProfile = true;
                        psdSaveOptions.alphaChannels = true;
                        psdSaveOptions.layers = true;
                        app.activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
                    }

                    if (layer.kind == "LayerKind.SMARTOBJECT") {
                        app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
                        SavePSD(saveName);
                    } else {
                        // Skip any layers that are not Smart Object layers    
                    }

                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                }

                // Reset visibility; 
                theLayer.visible = theVisibility;
            }
        } else {
            processSOLayers(theLayer);
        }
    }
    
    alert("Script Time: " + totalTime.getElapsed());
}
/* Main Code Finish */
}

/* Start Open/Saved Document Error Check - Part B: Catch */
  catch (err) {
    alert("An image must be open and saved before running this script!");
  }
}
/* Finish Open/Saved Document Error Check - Part B: Catch */

 

 

Likes

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
Reply
Loading...
Jan 03, 2021 1