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

Script to create smart object with layercomps from selected imageds in Bridge?

Enthusiast ,
Feb 17, 2022 Feb 17, 2022

Copy link to clipboard

Copied

I'd love a script  for Photoshop or maybe for   Bridge directly   that would  make a number of selected images into  a single smart object with those images inside  and listed  as switchable  layercomps. 

 So for example  I could just select 4 images of a CG material:  color, normal map, spec map and height    and drop it as a single smart object in Photoshop  with all 4 made into layercomps inside  with same names .

 

Have anyone ever tried to do something like this?

TOPICS
Actions and scripting

Views

1.1K

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 , Feb 19, 2022 Feb 19, 2022

This slightly modified version of the original script will allow the user to select multiple files in the standard Photoshop open dialog to create the stack:

 

/*
Selected files to smart object layer comps.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-create-smart-object-with-layercomps-from-selected-imageds-in-bridge/td-p/12760410
Stephen Marsh, v1.0
*/

#target photoshop

(function () {
    var savedDisplayDialogs = app.displayDialogs;
    app.displayDialogs = Di
...

Votes

Translate

Translate
Adobe
Community Expert ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied

Which part of the process is giving you problems? 

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 ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied

Just curious about the workflow? You obviously have to edit the smart object to change layer comp, I presume that you save and close to update with a new comp. What advantage does the comp offer in the workflow?

 

Can you provide screenshots to illustrate?

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 ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied

If the renderings might need further work and get replaced later on I suspect using Linked Smart Objects might provide an alternative. 

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
Enthusiast ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied

kirkr5689_0-1645228959712.png

 

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
Enthusiast ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied

I see a script 'load files into Stack'  that can collect images into a single smart object.   I 'd love something like that but with all images staying linked to its sources inside that smart object and be listed as layer comps to switch  in between  from   parent  smart object  they are collected inside   without opening and save/close it.    It's the  advantage .    I mean to automate the process  

Not sure how to illustrate it in a screenshot.

 

Maybe a better way woud be  Alt+drop images from Bridge into a new document in Photoshop and convert them into a smart object   than I need a script that would  list all  layers inside that smart object as  layercomps of same names and respective layer on only .      Basically a script that  would copy selected  layers names into Layer Comps  and make  those layer coms showing only single respective layer.

 

 

 

 

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 ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied


@kirkr5689 wrote:

 

Not sure how to illustrate it in a screenshot.

 

Loading files into a stack is not the issue, there are multiple ways to do this.

 

Creating a smart object from the stack is not the issue, there are multiple ways to do this.

 

Understanding what you wish to do with the layer comps is the sticking point for me.

 

When opening the smart object, it would contain 4 layers from your earlier example:

 

  • color
  • normal map
  • spec map
  • height

 

Do you require 4 separate layer visibility comps? One for each layer, with only a single visible layer per comp?

 

Will the layers always be a count of 4 and always use these names, or will the count and names vary?

 

Edit: your screenshot only shows 2 layers however I think that it answers some questions.

 

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
Enthusiast ,
Feb 18, 2022 Feb 18, 2022

Copy link to clipboard

Copied

I'd prefer it working just as in my screen, by copy/pasting   layers names  or names of Alt+dropped linked  files  into layer comps .   So count and names  vary  based on what have been dropped  into Photoshop.  And yes, each layer com make visiable  only single respective layer with those  checked in

kirkr5689_0-1645232421490.png

 

 

 

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 ,
Feb 19, 2022 Feb 19, 2022

Copy link to clipboard

Copied

This Photoshop script will stack all files from the selected folder to a new file named "Stacker" with a single parent smart object layer with linked smart object child layers and layer comps named after the layers.

 

/*
Image folder files to smart object layer comps.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-create-smart-object-with-layercomps-from-selected-imageds-in-bridge/td-p/12760410
Stephen Marsh, v1.0
*/

#target photoshop

(function () {
    var savedDisplayDialogs = app.displayDialogs;
    app.displayDialogs = DialogModes.NO;
    var origUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    var inputFolder = Folder.selectDialog('Please select the input folder:');
    if (inputFolder === null) {
        app.beep();
        return;
    }

    var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb|gif)$/i);
    // inputFiles.sort().reverse;
    inputFiles.sort();

    app.displayDialogs = DialogModes.NO;

    var baseDoc = open(inputFiles[0]);
    var baseDoc = app.activeDocument;
    baseDoc.flatten();
    baseDoc.duplicate("Stacker", false);
    baseDoc.close(SaveOptions.DONOTSAVECHANGES);

    for (var i = 0; i < inputFiles.length; i++) {
        placeFile(new File(inputFiles[i]), true, 0, 0);
    }

    app.activeDocument.activeLayer = app.activeDocument.backgroundLayer;
    app.activeDocument.activeLayer.remove();

    revealAll();
    //align2SelectAll('AdCH');
    //align2SelectAll('AdCV');
    app.runMenuItem(stringIDToTypeID("selectAllLayers"));

    createSmartObject();
    app.activeDocument.activeLayer.name = 'Layer Comp Stack';
    app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));

    for (var i = 0; i < app.activeDocument.layers.length; i++) {
        for (var j = 0; j < app.activeDocument.layers.length; j++) {
            app.activeDocument.layers[j].visible = false;
        }
        var layerIndex = i;
        app.activeDocument.layers[layerIndex].visible = true;
        var compName = app.activeDocument.layers[layerIndex].name;
        app.activeDocument.layerComps.add(compName, undefined, true, false, true, true);
        // Need to add a close step that actually saves the layer comps into the PSB! 
        var idsave = stringIDToTypeID( "save" );
        executeAction(idsave, undefined, DialogModes.NO);
    }

    //app.runMenuItem(stringIDToTypeID("selectAllLayers"));
    //reverseLayerStack();
    app.beep();
    app.displayDialogs = savedDisplayDialogs;
    app.preferences.rulerUnits = origUnits;


    // Functions

    function revealAll() {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        executeAction(s2t('revealAll'), descriptor, DialogModes.NO);
    }

    function createSmartObject() {
        try {
            var id325 = stringIDToTypeID("newPlacedLayer");
            executeAction(id325, undefined, DialogModes.NO);
        } catch (e) {
            alert("Error: Failed to make smart object " + e)
        }
    }

    function placeFile(null2, linked, horizontal, vertical) {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var AD = new ActionDescriptor();
        AD.putInteger(s2t("ID"), 1);
        AD.putPath(s2t("null"), null2);
        AD.putBoolean(s2t("linked"), linked); // false for embedded
        AD.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
        AD.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
        AD.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
        AD.putObject(s2t("offset"), s2t("offset"), AD);
        executeAction(s2t("placeEvent"), AD, DialogModes.NO);
    }

    function reverseLayerStack() {
        var idreverse = stringIDToTypeID("reverse");
        var desc4653 = new ActionDescriptor();
        var idnull = stringIDToTypeID("null");
        var ref2335 = new ActionReference();
        var idlayer = stringIDToTypeID("layer");
        var idordinal = stringIDToTypeID("ordinal");
        var idtargetEnum = stringIDToTypeID("targetEnum");
        ref2335.putEnumerated(idlayer, idordinal, idtargetEnum);
        desc4653.putReference(idnull, ref2335);
        executeAction(idreverse, desc4653, DialogModes.NO);
    }

    function align2SelectAll(method) {
        /*
        AdLf = Align Left
        AdRg = Align Right
        AdCH = Align Centre Horizontal
        AdTp = Align Top
        AdBt = Align Bottom
        AdCV = Align Centre Vertical
        */
        app.activeDocument.selection.selectAll();
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        desc.putReference(charIDToTypeID("null"), ref);
        desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
        try {
            executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
        } catch (e) {}
        app.activeDocument.selection.deselect();
    }
})();

 

NOTE: Layer comps add filesize overhead, an alternative to comps would be to simply opt/alt click the layer visibility eye icon of the desired layer to make it visible while hiding the other layers.

 

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

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 ,
Feb 19, 2022 Feb 19, 2022

Copy link to clipboard

Copied

This slightly modified version of the original script will allow the user to select multiple files in the standard Photoshop open dialog to create the stack:

 

/*
Selected files to smart object layer comps.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-create-smart-object-with-layercomps-from-selected-imageds-in-bridge/td-p/12760410
Stephen Marsh, v1.0
*/

#target photoshop

(function () {
    var savedDisplayDialogs = app.displayDialogs;
    app.displayDialogs = DialogModes.NO;
    var origUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    var inputFiles = File.openDialog("Please select the files to stack:", Multiselect = true);
    if (inputFiles === null) {
        app.beep();
        return;
    }
    // inputFiles.sort().reverse;
    inputFiles.sort();

    app.displayDialogs = DialogModes.NO;

    var baseDoc = open(inputFiles[0]);
    var baseDoc = app.activeDocument;
    baseDoc.flatten();
    baseDoc.duplicate("Stacker", false);
    baseDoc.close(SaveOptions.DONOTSAVECHANGES);

    for (var i = 0; i < inputFiles.length; i++) {
        placeFile(new File(inputFiles[i]), true, 0, 0);
    }

    app.activeDocument.activeLayer = app.activeDocument.backgroundLayer;
    app.activeDocument.activeLayer.remove();

    revealAll();
    //align2SelectAll('AdCH');
    //align2SelectAll('AdCV');
    app.runMenuItem(stringIDToTypeID("selectAllLayers"));

    createSmartObject();
    app.activeDocument.activeLayer.name = 'Layer Comp Stack';
    app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));

    for (var i = 0; i < app.activeDocument.layers.length; i++) {
        for (var j = 0; j < app.activeDocument.layers.length; j++) {
            app.activeDocument.layers[j].visible = false;
        }
        var layerIndex = i;
        app.activeDocument.layers[layerIndex].visible = true;
        var compName = app.activeDocument.layers[layerIndex].name;
        app.activeDocument.layerComps.add(compName, undefined, true, false, true, true);
        // Need to add a close step that actually saves the layer comps into the PSB! 
        var idsave = stringIDToTypeID( "save" );
        executeAction(idsave, undefined, DialogModes.NO);
    }

    //app.runMenuItem(stringIDToTypeID("selectAllLayers"));
    //reverseLayerStack();
    app.beep();
    app.displayDialogs = savedDisplayDialogs;
    app.preferences.rulerUnits = origUnits;


    // Functions

    function revealAll() {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        executeAction(s2t('revealAll'), descriptor, DialogModes.NO);
    }

    function createSmartObject() {
        try {
            var id325 = stringIDToTypeID("newPlacedLayer");
            executeAction(id325, undefined, DialogModes.NO);
        } catch (e) {
            alert("Error: Failed to make smart object " + e)
        }
    }

    function placeFile(null2, linked, horizontal, vertical) {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var AD = new ActionDescriptor();
        AD.putInteger(s2t("ID"), 1);
        AD.putPath(s2t("null"), null2);
        AD.putBoolean(s2t("linked"), linked); // false for embedded
        AD.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
        AD.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
        AD.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
        AD.putObject(s2t("offset"), s2t("offset"), AD);
        executeAction(s2t("placeEvent"), AD, DialogModes.NO);
    }

    function reverseLayerStack() {
        var idreverse = stringIDToTypeID("reverse");
        var desc4653 = new ActionDescriptor();
        var idnull = stringIDToTypeID("null");
        var ref2335 = new ActionReference();
        var idlayer = stringIDToTypeID("layer");
        var idordinal = stringIDToTypeID("ordinal");
        var idtargetEnum = stringIDToTypeID("targetEnum");
        ref2335.putEnumerated(idlayer, idordinal, idtargetEnum);
        desc4653.putReference(idnull, ref2335);
        executeAction(idreverse, desc4653, DialogModes.NO);
    }

    function align2SelectAll(method) {
        /*
        AdLf = Align Left
        AdRg = Align Right
        AdCH = Align Centre Horizontal
        AdTp = Align Top
        AdBt = Align Bottom
        AdCV = Align Centre Vertical
        */
        app.activeDocument.selection.selectAll();
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        desc.putReference(charIDToTypeID("null"), ref);
        desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
        try {
            executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
        } catch (e) {}
        app.activeDocument.selection.deselect();
    }
})();

 

 

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
Enthusiast ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

Thanks  you very much  Stephen .   Works perfect.    Now  would be super cool if we could start it from selection files in Bridge

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 ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied


@kirkr5689 wrote:

Thanks  you very much  Stephen .   Works perfect.    Now  would be super cool if we could start it from selection files in Bridge


 

Thanks.

 

Easier said than done (for me).

 

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 ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

This can be used to get an Array of the files selected in Bridge: 

alert(getSelectedFilesFromBridge().join('\n'));  
  
function getSelectedFilesFromBridge(){  
if (!BridgeTalk.isRunning("bridge")) {  
BridgeTalk.launch("bridge");  
var err = ["Bridge was not running, please run this script again\n Bridge will now be started."];  
return err;
}  
fileList = new Array();  
var bt = new BridgeTalk();  
bt.target = "bridge";  
bt.body = "var f = " + Script.toSource() + "; f();";  
bt.onResult = function( inBT ) { fileList =eval( inBT.body );}  
bt.onError = function( inBT ) { alert(eval(inBT.body)); }  
bt.send(8);  
return fileList;  
};  
  
function Script(){  
var sels = app.document.selections;  
var Files=[];  
if(!sels.length) Files.push("No Files Selected");  
for(var z =0; z < sels.length;z++){  
if(sels[z].spec instanceof File) {  
Files.push(sels[z].spec);  
    }  
}  
return Files.toSource();  
};

 

Unfortunately I don’t remember who originally provided it, I saved a link but that thread seems to have fallen by the wayside in the recent Forum-update. 

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
LEGEND ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

LATEST

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 ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

This would create copies and apply the Layer Comps to a Smart Object.

// create instances of smart object and apply all layer comps;
// 2022, use it at your own risk;
if (app.documents.length > 0) {
var ref = new ActionReference();	
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var layerDesc = executeActionGet(ref);
if (layerDesc.hasKey(stringIDToTypeID("smartObject")) == true) {
var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
var x = theSO.getList(stringIDToTypeID("compsList"));
var theCompsList = theSO.getObjectValue(stringIDToTypeID("compsList"));
if (theCompsList.count > 2) {
var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
var theSOComps = new Array;
for (var m = 0; m < theCompsList.count; m++) {
var thisOne = theCompsList.getObjectValue(m);
var theName = thisOne.getString(stringIDToTypeID("name"));
var theID = thisOne.getInteger(stringIDToTypeID("ID"));
var theComment = thisOne.getString(stringIDToTypeID("comment"));
theSOComps.push([theName, theID, theComment])
};
var theSOMore = layerDesc.getObjectValue(stringIDToTypeID("smartObjectMore"));
var appliedComp = theSOMore.getInteger(stringIDToTypeID("comp"));
// create copies and applylayercomp;
for (var n = 0;n < theSOComps.length;n++) {
    var thisComp = theSOComps[n];
    if (appliedComp != thisComp[1]) {
        executeAction( charIDToTypeID( "CpTL" ), undefined, DialogModes.NO );
        applyLayerCompToSmartObject(thisComp[1])
    }
}
}
}
};
////// apply layercomp to smart object //////
function applyLayerCompToSmartObject (theID) {
    // =======================================================
        var desc9 = new ActionDescriptor();
            var ref3 = new ActionReference();
            ref3.putEnumerated(charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
        desc9.putReference( charIDToTypeID( "null" ), ref3 );
        desc9.putInteger( stringIDToTypeID( "compID" ), theID );
    executeAction( stringIDToTypeID( "setPlacedLayerComp" ), desc9, DialogModes.NO );
    };

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
Enthusiast ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

c.pfaffenbichler

Thanks. but I couldn't seem to  figure out how to use it. Coudld you explain please.  Nothing happens  after I  run the script

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 ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

Is the active Layer a Smart Object that has Layer Comps? 

If not then nothing is supposed to happen. 

If the active Layer is a Smart Object with Layer Comps, then it should get copied as many times as necessary to apply all Layer Comps and those appied to the instances. 

 

I thought that was part of the original idea. 

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
Enthusiast ,
Feb 21, 2022 Feb 21, 2022

Copy link to clipboard

Copied

It's a nice script indeed and might be useful  too but not  what I suggested.  My idea was  to drop with Alt pressed a few files from Bridge  into a new photoshop document , convert them to a single smart object  and then having a script that would  do layer comps  from those files inside.

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