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

Is it possible to make the name of combined layers the bottom one's?

Contributor ,
May 05, 2021 May 05, 2021

Copy link to clipboard

Copied

Sorry for the bad English in the title. What I mean is, for example I have 3 layers

top - Edit 2

mid - Edit

bot - Main layer with a name that makes sense

When I combine them together, the name of the combined layer becomes "Edit 2". Is it possible to make it the bottom one with a setting? Maybe with an action? 

(just to be clear, it is not always 3 layers and the names are not "Edit, Edit2" etc.)

TOPICS
Actions and scripting

Views

10.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 6 Correct answers

Community Expert , May 05, 2021 May 05, 2021

To you can automate that process with a Photoshop Script, Action can not use logic to see the Layer names  that are being merged and rename the merged layer name to what you want based on the former layer names.  Script can use the required logic to do what you wan to automate.

Votes

Translate

Translate
Community Expert , May 06, 2021 May 06, 2021

The previous script ran in approx. 6.7 seconds to run on a random set of 3 layers stacked.

 

The new code below took approx. 4 seconds for the same 3 layers.

 

It's still a less than ideal hack though... A better coder than me should be able to make this much faster. Can somebody upgrade my code?

 

EDIT: It appears that the best/common way is to temporarily group the selected layers, then do something with the group (rather than with a new doc as my second script uses).

 

 

 

/*
Select all requi
...

Votes

Translate

Translate
Contributor , May 07, 2021 May 07, 2021

I think making it run in 2 steps is a bad idea because purpose of the script is making it work with single click, and seamless if possible. 

And, it is indeed possible. With some external help as well, I managed to write this. It works without opening SO (which I didn't like), but it can be a bit slower with bigger files (very little tho). I personally prefer this.  

 

/*
Create a new smart object with the bottom layer's name
Gökhan Şimşek - 7.5.21
v1.1
*/

#target photoshop

var myDoc = app.active
...

Votes

Translate

Translate
Community Expert , May 07, 2021 May 07, 2021

I modified the get selected layers  code I posted to create the smart object layer,  As the cods stands the Smart object layer  name will be the bottom not the top name.  However, there is code that is commented out.  That code would make the layer name the list of merged layers.

 

app.activeDocument.suspendHistory('makeSmartObject','main()');

function main() {
	try {
		var selectedLayers = get_selected_layers_id();
		var	Names = (get_layer_by_id(selectedLayers[0]).name); 
		/*
		var Names = ""
...

Votes

Translate

Translate
LEGEND , Aug 05, 2021 Aug 05, 2021

 

sTT = stringIDToTypeID;
(ref = new ActionReference()).putEnumerated
(sTT('layer'), sTT('ordinal'), sTT('targetEnum'));
(dsc = new ActionDescriptor()).putReference(sTT('null'), ref)
executeAction(sTT('linkSelectedLayers'), dsc)
with((actveDcmnt = activeDocument).activeLayer)
	nme = linkedLayers.pop().name, merge()
actveDcmnt.activeLayer.name = nme

 

or:

 

(aD = activeDocument).suspendHistory('', ''), aHS = aD.activeHistoryState
	sTT = stringIDToTypeID, dsc = new ActionDescriptor(), arr = ['back
...

Votes

Translate

Translate
Guide , Aug 07, 2021 Aug 07, 2021

I did not see the simplest way - to get the name of the 1st target layer and assign it after convert to SO.

 

function main() {
	var s2t = stringIDToTypeID;

	(tr = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
	tr.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));

	(lr = new ActionReference).putProperty(s2t('property'), n = s2t('name'));
	lr.putIdentifier(s2t('layer'), executeActionGet(tr).getList(p).getReference(0).getIdentifier(s2t('layerID')));
...

Votes

Translate

Translate
Adobe
Community Expert ,
May 07, 2021 May 07, 2021

Copy link to clipboard

Copied

@Mugen777  Great job! That is what I was trying to achieve, however, without knowing how to use arrays I couldn't get there.

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
Contributor ,
May 08, 2021 May 08, 2021

Copy link to clipboard

Copied

I had some experience from AE scripting, but the idea itself from someone else, so he deserves the credit here : )

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 ,
May 07, 2021 May 07, 2021

Copy link to clipboard

Copied

I modified the get selected layers  code I posted to create the smart object layer,  As the cods stands the Smart object layer  name will be the bottom not the top name.  However, there is code that is commented out.  That code would make the layer name the list of merged layers.

 

app.activeDocument.suspendHistory('makeSmartObject','main()');

function main() {
	try {
		var selectedLayers = get_selected_layers_id();
		var	Names = (get_layer_by_id(selectedLayers[0]).name); 
		/*
		var Names = "";
		for ( var i = selectedLayers.length; i > 0; i-- ) { 
			thisLayer = get_layer_by_id(selectedLayers[i-1]);
			if (Names=="") Names = thisLayer.name;
			else Names = Names + "-" + thisLayer.name;
		}
		*/
		newPlacedLayer();
		app.activeDocument.activeLayer.name = Names;
	}
	catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }
} 

function get_selected_layers_id() {  
	try {  
		var r = new ActionReference();      
		r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("targetLayers"));      
		r.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));  
		var d = executeActionGet(r);  
		if (!d.hasKey(stringIDToTypeID("targetLayers"))) {  
			var r = new ActionReference();  
			r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("layerID"));      
			r.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));  
			return [ executeActionGet(r).getInteger(stringIDToTypeID("layerID")) ];  
        }  
		var list = d.getList(stringIDToTypeID("targetLayers"));  
		if (!list) return null;  
		var n = 0;  
		try { activeDocument.backgroundLayer } catch (e) { n = 1; }  
		var len = list.count;  
		var selected_layers = new Array();  
		for (var i = 0; i < len; i++) {  
			try {  
				var r = new ActionReference();  
				r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("layerID"));      
				r.putIndex( charIDToTypeID("Lyr "), list.getReference(i).getIndex() + n);  
				selected_layers.push(executeActionGet(r).getInteger(stringIDToTypeID("layerID")));  
			}  
			catch (e) { _alert(e); return null; }  
		}  
		return selected_layers;  
	}  
	catch (e) { alert(e); return null; }  
} 
 
function get_layer_by_id(id, doc_id) {    
	try {    
		var doc;  
		if (doc_id == undefined) doc = activeDocument;  
		else { 
			for (var i = 0; i < documents.length; i++) {  
				if (documents[i].id == doc_id) {  
					doc = documents[i];  
					break;  
                }  
            }
		}
		if (doc == undefined) { alert("Bad document " + doc_id); return null; }  
		var r = new ActionReference();      
		r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("json"));   
		if (doc_id == undefined) r.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));  
		else                     r.putIdentifier(charIDToTypeID("Dcmn"), doc_id);  
		eval("var json = " + executeActionGet(r).getString(stringIDToTypeID("json")));    
		if (json == undefined) return null;    
		var set = new Array();  
		function search_id(layers, id) {    
			for (var i = 0; i < layers.length; i++) {  
				if (layers[i].id == id) { set.push(i); return true; }  
            }  
			for (var i = 0; i < layers.length; i++) {  
				if (layers[i].layers) {    
					if (search_id(layers[i].layers, id)) { set.push(i); return true; }   
				}  
			}  
		}     
		if (search_id(json.layers, id)) {  
			var ret = doc.layers;  
			for (var i = set.length-1; i > 0; i--) { ret = ret[set[i]].layers;}  
			return ret[set[0]];  
		}  
		return null;  
	}    
	catch (e) { alert(e); }    
}

function newPlacedLayer() {
	executeAction( stringIDToTypeID( "newPlacedLayer" ), undefined, DialogModes.NO );
}

 

JJMack

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 ,
May 07, 2021 May 07, 2021

Copy link to clipboard

Copied

Nice one!

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 ,
Aug 05, 2021 Aug 05, 2021

Copy link to clipboard

Copied

 

(aD = activeDocument)
.suspendHistory('', '')
sTT = stringIDToTypeID
aHS = aD.activeHistoryState
ref2 = new ActionReference();
(ref1 = new ActionReference()).putEnumerated
(sTT('layer'), sTT('ordinal'), sTT('targetEnum'));
(dsc = new ActionDescriptor()).putReference(sTT('null'), ref1);
ref2.putEnumerated(sTT('layer'), sTT('ordinal'), sTT('back'))
dsc.putReference(sTT('to'), ref2), executeAction(sTT('move'), dsc);
nme = ((lst = (lrs = aD.layers)[lrs.length - 1]).isBackgroundLayer ? lrs[lrs.length - 2] : lst).name
aD.activeHistoryState = aHS, runMenuItem(sTT('newPlacedLayer')), aD.activeLayer.name = nme

 

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
Guide ,
Aug 05, 2021 Aug 05, 2021

Copy link to clipboard

Copied

nme = (lst = (lrs = aD.layers)[lrs.length - 1]).isBackgroundLayer ? lrs[lrs.length - 2].name : lst.name

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 ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

Thank you for finding it - I corrected it. Originally it's how that line looked liked, but then I started changing it to other version and forgot to finish it:

 

nme = ((lst = (lrs = aD.layers)[lrs.length - 1]).isBackgroundLayer ? lrs[lrs.length - 2] : lst).name

 

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 ,
Aug 05, 2021 Aug 05, 2021

Copy link to clipboard

Copied

quote

Have you looked at targeting the top layer and then using "merge down" – CMD/CTRL E as many times as required?

 

No need for a script, however, you could record an action to automate this command for 2, 3 or more "sets" of layers which will all retain the bottom name.

 

By @Stephen_A_Marsh

 

Stephen, I asked the same question as the OP a while back and, I thgink it was Christoph who came with an answer, but I didn't make a note of it at the time, (my bad) so I can't remember if he suggested Ctrl e. 

 

@c.pfaffenbichler was it you, and is the answer you gave 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 ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

If you merge down a layers. The upper layers content is merged into the lower layer the top layer and its name is deleted it no longer exists. The lower layer still exist with changed content. So yes the lowest layer  should be the remaining layer.  So yes  no script is requires if you are merging down.  However the OP was not merging down. They create a smart object layer where the Top layer name becomes the name  of the smart object layer name.  They wanted the bottom layer name to be the Smart objects layers name. The layers still exists in the object.

JJMack

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 ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

No c.pfaffenbichler in this thread.

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 ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

quote

No c.pfaffenbichler in this thread.


By @Kukurykus

 

You need to expand your horizons.  There is an entire world outside of this thread.

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 ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

LATEST

You're too experienced to ask basic questions so I understood that other way 😉

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 ,
Aug 05, 2021 Aug 05, 2021

Copy link to clipboard

Copied

 

sTT = stringIDToTypeID;
(ref = new ActionReference()).putEnumerated
(sTT('layer'), sTT('ordinal'), sTT('targetEnum'));
(dsc = new ActionDescriptor()).putReference(sTT('null'), ref)
executeAction(sTT('linkSelectedLayers'), dsc)
with((actveDcmnt = activeDocument).activeLayer)
	nme = linkedLayers.pop().name, merge()
actveDcmnt.activeLayer.name = nme

 

or:

 

(aD = activeDocument).suspendHistory('', ''), aHS = aD.activeHistoryState
	sTT = stringIDToTypeID, dsc = new ActionDescriptor(), arr = ['back', 'for']; while(arr.length)
		(ref = new ActionReference()).putEnumerated(sTT('layer'), sTT('ordinal'), sTT(arr.shift() + 'wardEnum')),
		dsc.putReference(sTT('null'), ref), executeAction(sTT('select'), dsc); nme = aD.activeLayer.name
aD.activeHistoryState = aHS, (lyr = aD.activeLayer).merge(), aD.activeLayer.name = nme

 

or else:

 

sTT = stringIDToTypeID;
(ref = new ActionReference()).putEnumerated
(sTT('layer'), sTT('ordinal'), sTT('targetEnum'));
(dsc = new ActionDescriptor()).putReference(sTT('null'), ref)
executeAction(sTT('groupLayersEvent'), dsc), aD.activeLayer.merge()
.name = (lrs = (aD = activeDocument).activeLayer.layers)[lrs.length - 1].name

 

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
Contributor ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

Hey there


Looks like it is faster than what I created before, I just changed 

    (lyr = aD.activeLayer).merge()

with 

    executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO)

to turn layers to smart object instead, and looks like it is lot better than before : ) 

Thank you!

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 ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

These versions were due your to original question, but after I found you changed mind to make Smart Object I wrote forth code accordingly to your new requirement: Aug 06, 20121

 

Regarding to the speed when using these codes for merging the fastest is 1st, then 3rd & 2nd. When using the 2nd code to make a smart object from layers it is as fast as the 4th code 🙂

 

I didn't expect you to show up after over 2 months, but if you are here add one of my answers to correct (fastest) solutions for some stray forum scripting wanderers 😉

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
Contributor ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

Yeah, I totally forget editing first post, my bad 🙂 

About 4.th code, it doesn't work. It does create Smart Object as intended, but it changes the name to an irrelevant folder's name. 

And actually now there is a problem about 2.nd code as well (that I edited, will post below). It does work, but if I duplicate a layer then try to use it on 3 other layers, it doesn't touch that 3 layers and makes the duplicated layer smart object instead. This is just an example I saw, I am not sure about other situations. 

function main(){ //to undo easily
(aD = activeDocument).suspendHistory('', ''), aHS = aD.activeHistoryState
	sTT = stringIDToTypeID, dsc = new ActionDescriptor(), arr = ['back', 'for']; while(arr.length)
		(ref = new ActionReference()).putEnumerated(sTT('layer'), sTT('ordinal'), sTT(arr.shift() + 'wardEnum')),
		dsc.putReference(sTT('null'), ref), executeAction(sTT('select'), dsc); nme = aD.activeLayer.name
aD.activeHistoryState = aHS,
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO), //Edited Line
aD.activeLayer.name = nme
}

//to undo easily
app.activeDocument.suspendHistory ("Smart Obj Script", "main()");

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 ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

I tried the 4th code and it works. What do you mean by 'it changes the name to an irrelevant folder's name.'? Maybe you have some specific layer(Set)s tree?

 

I tried now also 2nd code. It works for me as well, using your version makes no difference, however I see there is suspendHistory inside of other suspendHistory that shouldn't be used.


"It does work, but if I duplicate a layer then try to use it on 3 other layers, it doesn't touch that 3 layers and makes the duplicated layer smart object instead. This is just an example I saw, I am not sure about other situations."

 

I can't imagine it. Would you mind to post a screenshot?

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
Contributor ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

Well, it is really weird. Let me tell you what exactly happens. 

I am always trying in the same project. I have a "main" folder (and few other folder and files), there are 20+ layers inside Main folder and I am using script on 3 visible layers. 

About 2.nd code, I duplicate one of the 20+ layers, and when I try to use script on the 3 visible layers like before, it just makes the duplicated layer smart object without touching other 3. Here, you can see it here -> efe8352a0e686e3b04f0e3a33e0d4d7e.mp4

I just realized, it only happens on my edited version. But I have no idea why 😕 

About 4th code, I only have folders and files in folders. When I use 4.th script on 3 visible files, it makes them smart object but names them "sketch" which is one of folder's name. 

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 ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

I was able to reproduce the issue with your (previously my 2nd) code on later duplicated layers. Like I said you cannot use suspendHistory() method inside other suspendHistory() method. Mine code already used this method, but then you put the whole code inside your function that uses it too. Just remove your main function, or make it regular function, so without suspendHistory method, and it will work 😉


In 4th code I also found what is problem. From your previous posts that didn't seem you will use selected layers contained in groups, so I made script for zero level layers. If you want it worked for both cases change:

 

lrs = aD.layers

 

to:

 

lrs = aD.activeLayer.parent.layers

 

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
Contributor ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

Looks like both of them work now 🙂 

But the thing is, I was using that main function to undo whole thing with only one ctrl-z. (I use undo a LoT). Anything I can do about it? 

And I am just curious, 4.th code always shows this error. I am just curious what is it. 

Mugen777_0-1628332800581.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
LEGEND ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

In second code move:

function main(){

over:

aD.activeHistoryState = aHS

 

In forth code change:

runMenuItem

to:

executeAction

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
Contributor ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

Yep, looks like both works very good right now : ) 

Just curious, which one would you advise? I am not sure how different they are to be honest : D 

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 ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

Both work with the same speed, but the 4th is designed for Smart Object 😉

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
Contributor ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

Then 4 is way to go! Thanks again : ) 

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 ,
Aug 07, 2021 Aug 07, 2021

Copy link to clipboard

Copied

Maybe not. I tested yours, and it is the fastest loll

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