Copy link to clipboard
Copied
Hello everyone! Sorry for my limited English that I could not explain it more clearly at the title. I really need a help, then I will tell it as details as possible:
For example, I have a smart object like this
Inside the Smart object, there are some text layers. The text layer and clipping masks are not fixed, sometimes ther are 2, sometimes are 5. But the text layers always in a group
My work requirements is separating these text into separate smart objects but keep the smart filter and original color inside, like this:
and so does I do that by New smart Object via Copy and edit content of every new object by keep hiding the others & showing the target text:
but now I met a super great smart object that contain 50+ text layers inside, and I've wasted half of a day just to separate it 🙂 I did known a script could split layer to layers, but I cannot rasterize the object because some need to modify then.
Anyone have an idea? I am extremely grateful that you could help!
Edit: I've added the sample inside the target file
I would prefer using Layer comps.
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
var theLayer = myDocument.activeLayer;
var theSO = openSmartObject ();
if (theSO == false) {alert ("please select the smart object")}
else {
var theTypeLayers = collectTypeLayers();
for (var m = 0; m < theTypeLayers.length; m++) {hideLayer (theTypeLayers[m][1])};
for (var m = 0; m < theTypeLayers.length; m++) {
showLayer (theTypeLayers[m][1]);
createLayerComp
...
may I ask for another request Sir? I've just realized that some contents in my objects not only text layers but also smart objects (instead of text). Could you provide this script a bit so that it will work with smart object too?
By @Junyi24858697x32l
I haven't tested this code, however, you could try changing this line from:
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
To:
if (
...
Copy link to clipboard
Copied
Copy link to clipboard
Copied
thank you for mentioning, I've added the target sample file ^^
Copy link to clipboard
Copied
OK, this is proving to be a little harder than I first thought! :]
This isn't the first time that I have bitten off more than I could chew...
So far the script will create a new smart object via copy for all of the required layers.
I have not yet worked out the bit around cycling over each smart object and turning off the visibility for the "unwanted" layers.
Perhaps another scripter could step in?
Anyway, I'll post what I have so far as it may speed up some of the work for you.
/*
WORK IN PROGRESS!
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-hide-and-show-contents-inside-the-smart-object/td-p/14673869
*/
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
// Edit the SO layer
app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
// Get the number of layers in the set
if (app.activeDocument.layerSets.length == 1) {
app.activeDocument.activeLayer = app.activeDocument.layerSets[0];
var theGroupLayers = app.activeDocument.activeLayer.layers.length;
//alert("There are " + theGroupLayers + " layers in the set...");
} else {
alert("There appears to be more than 1 layer group! Script cancelled...");
}
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// New smart object via copy N times
var dupeValue = theGroupLayers - 1;
for (var i = 0; i < dupeValue; i++) {
executeAction( stringIDToTypeID( "placedLayerMakeCopy" ), undefined, DialogModes.NO );
}
// To do - loop over the SO layers and turn the correct text layers off one by one... Easier said than done!
} else {
alert("The active layer isn't a Smart Object layer!");
}
Copy link to clipboard
Copied
thank you for helping me Sir! My request is difficult to comply with, but may I ask that if I rename the text layer into number like this, would it be more possible for you?
Copy link to clipboard
Copied
if I rename the text layer into number like this, would it be more possible for you?
By @Junyi24858697x32l
I don't think so. I'm hoping that the answer may be obvious to another scripter (what's hard for one person is easy for another with more knowledge and experience).
I think that I just need to take a break and think about this from another angle.
Copy link to clipboard
Copied
I would prefer using Layer comps.
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
var theLayer = myDocument.activeLayer;
var theSO = openSmartObject ();
if (theSO == false) {alert ("please select the smart object")}
else {
var theTypeLayers = collectTypeLayers();
for (var m = 0; m < theTypeLayers.length; m++) {hideLayer (theTypeLayers[m][1])};
for (var m = 0; m < theTypeLayers.length; m++) {
showLayer (theTypeLayers[m][1]);
createLayerComp (theTypeLayers[m][0]);
hideLayer (theTypeLayers[m][1]);
};
showLayer (theTypeLayers[0][1]);
theSO.close(SaveOptions.SAVECHANGES);
var theComps = collectSmartObjectsLayerComps ();
for (var n = 0; n < theComps.length; n++) {
var theDup = theLayer.duplicate();
myDocument.activeLayer = theDup;
applyLayerCompToSmartObject (0, theComps[n][1]);
theDup.name = theComps[n][0];
};
theLayer.visible = false;
}
};
////////////////////////////////////
function collectTypeLayers () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
theLayers.push([theName, theID])
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
////// open smart object //////
function openSmartObject () {
try {
var desc2 = new ActionDescriptor();
executeAction( stringIDToTypeID( "placedLayerEditContents" ), desc2, DialogModes.NO );
return app.activeDocument
} catch (e) {return false}
};
////// create layer comp //////
function createLayerComp (theName) {
// =======================================================
var desc4 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putClass( stringIDToTypeID( "compsClass" ) );
desc4.putReference( stringIDToTypeID( "null" ), ref2 );
var desc5 = new ActionDescriptor();
desc5.putBoolean( stringIDToTypeID( "useVisibility" ), true );
desc5.putBoolean( stringIDToTypeID( "usePosition" ), true );
desc5.putBoolean( stringIDToTypeID( "useAppearance" ), true );
desc5.putBoolean( stringIDToTypeID( "useChildLayerCompState" ), true );
desc5.putString( stringIDToTypeID( "title" ), theName );
var idcompsClass = stringIDToTypeID( "compsClass" );
desc4.putObject( stringIDToTypeID( "using" ), idcompsClass, desc5 );
executeAction( stringIDToTypeID( "make" ), desc4, DialogModes.NO );
};
////// apply layercomp to smart object //////
function applyLayerCompToSmartObject (theLayerID, theID) {
if (theLayerID != 0) {selectLayerByID(theLayerID, false)};
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 );
};
//////
function hideLayer (theID) {
var desc4 = new ActionDescriptor();
var list1 = new ActionList();
var ref1 = new ActionReference();
ref1.putIdentifier( stringIDToTypeID( "layer" ), theID);
list1.putReference( ref1 );
desc4.putList( stringIDToTypeID( "null" ), list1 );
executeAction( stringIDToTypeID( "hide" ), desc4, DialogModes.NO );
};
//////
function showLayer (theID) {
var desc4 = new ActionDescriptor();
var list1 = new ActionList();
var ref1 = new ActionReference();
ref1.putIdentifier( stringIDToTypeID( "layer" ), theID);
list1.putReference( ref1 );
desc4.putList( stringIDToTypeID( "null" ), list1 );
executeAction( stringIDToTypeID( "show" ), desc4, DialogModes.NO );
};
////// collect smart object’s layer comps, probably based on code by paul, mike or x //////
function collectSmartObjectsLayerComps () {
try {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
//ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
// is smart object;
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
// comps;
var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
var theCompsList = theSO.getObjectValue(stringIDToTypeID("compsList"));
if (theCompsList.count > 2) {
var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
var theSOComps = new Array;
for (var n = 0; n < theCompsList.count; n++) {
var thisOne = theCompsList.getObjectValue(n);
var theCompName = thisOne.getString(stringIDToTypeID("name"));
var theCompID = thisOne.getInteger(stringIDToTypeID("ID"));
var theComment = thisOne.getString(stringIDToTypeID("comment"));
theSOComps.push([theCompName, theCompID, theComment]);
};
// add to array;
return theSOComps
//return [theName, theID, theSOComps]
}
}
}
} catch (e) {};
};
////// get active layer’s id //////
function getLayerId () {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("layerID"));
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
return executeActionGet(ref).getInteger(stringIDToTypeID("layerID"));
};
Copy link to clipboard
Copied
OMG thank you so much!!! The script worked so fast and perfectly, you really saved our day!
Copy link to clipboard
Copied
may I ask for another request Sir? I've just realized that some contents in my objects not only text layers but also smart objects (instead of text). Could you provide this script a bit so that it will work with smart object too?
Copy link to clipboard
Copied
may I ask for another request Sir? I've just realized that some contents in my objects not only text layers but also smart objects (instead of text). Could you provide this script a bit so that it will work with smart object too?
By @Junyi24858697x32l
I haven't tested this code, however, you could try changing this line from:
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
To:
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true || layerDesc.hasKey(stringIDToTypeID("smartObject")) == true) {
Copy link to clipboard
Copied
@c.pfaffenbichler – as always, you rock!
Copy link to clipboard
Copied
dear Sirs, I'm here to thank to you all that the script really helped us a lot! But now I met trouble when I tried to modify some of the smart objects that splitted. They only show just one top layer inside the group, although it's not the layer that visible. I tried to convert an object to layers, it jumped into the layer that shown inside the object although it shown the other layer before. Could you guy check if there's something's wrong?