Skip to main content
Participant
May 17, 2020
Answered

Smart Objects in separate layers

  • May 17, 2020
  • 4 replies
  • 6045 views

I have a file with over 150 layers. I'd like to convert each layer to a smart object, but can only find an answer to converting them all to one Smart Object, instead of individual ones. Any clues anyone? Is there any Action I can download perhaps? 

 

This topic has been closed for replies.
Correct answer jazz-y

also not very fast - converting to a smart object is a rather time memory-consuming operation.

 

#target photoshop

s2t = stringIDToTypeID;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var sel = executeActionGet(r).hasKey(p) ? executeActionGet(r).getList(p) : null;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('hasBackgroundLayer'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var shift = executeActionGet(r).getBoolean(p) ? 0: 1

if (sel) {
    for (var i = 0; i < sel.count; i++) {
        (r = new ActionReference()).putIndex(s2t("layer"), sel.getReference(i).getIndex() + shift);
        (d = new ActionDescriptor()).putReference(s2t("null"), r);
        executeAction(s2t("select"), d, DialogModes.NO)
        executeAction(s2t("newPlacedLayer"), undefined, DialogModes.NO);
    }
}

 

 

4 replies

Stephen Marsh
Community Expert
Community Expert
January 4, 2022
JJMack
Community Expert
Community Expert
May 17, 2020

Smart object layers have high overhead, lots of baggage and some restrictions.    Your most likely do not want to have 150 smart object layer in a document. They a a special purpose type layer, not a general use layer type.

JJMack
Stephen Marsh
Community Expert
Community Expert
May 17, 2020

Another option is to create a simple 2 step action, which would convert the current layer or set to a smart object, then select the next layer down:

 

 

Then, a script that repeats an action could be run, however, you have to enter in the exact number of repetitions required:

 

 

// Repeat action N times
// https://forums.adobe.com/thread/2649334
// https://forums.adobe.com/message/11234144#11234144
#target photoshop
function main() {
    for (i = 0; i < 150; i++) // Change the number 150 to be however many times the action should be repeated
    {
        app.doAction("Run", "Make SO Layer"); // Change the action and action set as required
    }
}
app.activeDocument.suspendHistory("Repeat action N times (history suspended)", "main()");

 

 

Then select the very top layer or layer set and run the script.

 

EDIT: This version uses a prompt GUI to enter the repetition number, rather than hard-coding the number into the script –

 

 

// Repeat action N times GUI
// https://forums.adobe.com/thread/2649334
// https://forums.adobe.com/message/11234144#11234144

#target photoshop

// Loop the input prompt until a number is entered
var origInput;
while (isNaN(origInput = prompt("Enter a whole number:", "150")));
// Convert decimal input to integer
var inputToInteger = parseInt(origInput);

function main() {
    for (i = 0; i < inputToInteger; i++) // Variable prompt N times
    {
        app.doAction("Run", "Make SO Layer"); // Change the action and action set as required
    }
}
app.activeDocument.suspendHistory("Repeat action N times (history suspended)", "main()");

 

 

EDIT: 7th June 2020 – Original input prompt replaced with more robust code!

 

Stephen Marsh
Community Expert
Community Expert
May 17, 2020

An action would need to have 150+ layer selection and conversion steps built-in.

 

Try this script (work on a duplicate file just in case it is not what you are looking for):

 

 

// convert all top level layers and layer sets to smart objects.jsx

function main() {

    if (!documents.length) {
        alert('There are no documents open!');
    } else {
        processAllLayersAndSets(app.activeDocument);
    }

    function processAllLayersAndSets(obj) {

        // Process all layers and layer sets
        // Change the following 2 entries of "obj.layers" to "obj.artLayers" to exclude layer sets
        for (var al = obj.layers.length - 1; 0 <= al; al--) {
            app.activeDocument.activeLayer = obj.layers[al];

            newPlacedLayer();

        }

        // Process Layer Set Layers 
        for (var ls = obj.layerSets.length - 1; 0 <= ls; ls--) {
            processAllLayersAndSets(obj.layerSets[ls]);

            newPlacedLayer();

        }
    }

    // Convert to smart object (Cleaned AM code)
    function newPlacedLayer() {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        executeAction(s2t("newPlacedLayer"), undefined, DialogModes.NO);
    }
}

activeDocument.suspendHistory('Smart Objects from Layers & Sets', 'main()');

 

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

P.S. This code may be a bit slow on 150+ layers, it uses standard JavaScript Reference DOM code, I don't know how to do this via Action Manager code which should be faster.

 

jazz-yCorrect answer
Legend
May 17, 2020

also not very fast - converting to a smart object is a rather time memory-consuming operation.

 

#target photoshop

s2t = stringIDToTypeID;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var sel = executeActionGet(r).hasKey(p) ? executeActionGet(r).getList(p) : null;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('hasBackgroundLayer'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var shift = executeActionGet(r).getBoolean(p) ? 0: 1

if (sel) {
    for (var i = 0; i < sel.count; i++) {
        (r = new ActionReference()).putIndex(s2t("layer"), sel.getReference(i).getIndex() + shift);
        (d = new ActionDescriptor()).putReference(s2t("null"), r);
        executeAction(s2t("select"), d, DialogModes.NO)
        executeAction(s2t("newPlacedLayer"), undefined, DialogModes.NO);
    }
}

 

 

Stephen Marsh
Community Expert
Community Expert
May 17, 2020

jazz-y - Thank you for sharing!

 

OK, this appears to work on selected layers only...

 

One possible issue, I had a layer set in my test, the set had a curves adjustment layer above a raster layer. The set was converted as expected to a SO, however,  when I opened the SO created from the set, all of the contents of the SO layer were also SO, even the adjustment layer! Having the adjustment layer turned into a SO obviously destroys it's effect on the lower raster layer.

 

My expectation is that only root/top level layers and sets should be converted to a SO layer, the contents of the SO layer should remain untouched and should not be converted into SO layers (unless they were already a SO before running the script).