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?
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
...
Copy link to clipboard
Copied
Which part of the process is giving you problems?
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?
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.
Copy link to clipboard
Copied
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.
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:
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.
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
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
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();
}
})();
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
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).
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.
Copy link to clipboard
Copied
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 );
};
Copy link to clipboard
Copied
Thanks. but I couldn't seem to figure out how to use it. Coudld you explain please. Nothing happens after I run the script
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.
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.