Get infos about all selected layers?

Contributor ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Hello,

Based on the following script found on the net (don't remember where exactly because I made lots of searches), is there a way to add more infos to the selected layers? I would like to know if a layer is a LayerSet or not, and also if it is "movable" (not locked and not background layer).

 

Please look at the "???" at the end of the script

 

function getSelectedLayersInfo() {
	var lyrs = [];
	var lyr;
	var ref = new ActionReference();
	var desc;
	var tempIndex = 0;
	var ref2;
	ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayers"));
	ref.putEnumerated(charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
	
	var targetLayers = executeActionGet(ref).getList(stringIDToTypeID("targetLayers"));
	for (var i = 0; i < targetLayers.count; i++) {
		ref2 = new ActionReference();
		// if there's a background layer in the document, AM indices start with 1, without it from 0
		try {
			activeDocument.backgroundLayer;
			ref2.putIndex(charIDToTypeID('Lyr '), targetLayers.getReference(i).getIndex());
			desc = executeActionGet(ref2);
			tempIndex = desc.getInteger(stringIDToTypeID("itemIndex")) - 1;
		} catch (o) {
			ref2.putIndex(charIDToTypeID('Lyr '), targetLayers.getReference(i).getIndex() + 1);
			desc = executeActionGet(ref2);
			tempIndex = desc.getInteger(stringIDToTypeID("itemIndex"));
		}
	
		lyr = {};
		lyr.index = tempIndex;
		lyr.id = desc.getInteger(stringIDToTypeID("layerID"));
		lyr.name = desc.getString(charIDToTypeID("Nm  "));
		///// lyr.isLayerSet = ???????
		///// lyr.isLocked = ???????
		///// lyr.isBackground = ???????
		lyrs.push(lyr);
	}
	
	return lyrs;
}

 

This script works fine on Photoshop CS6, but doesn't return enough informations about selected layers for my use.

 

Thank you.

TOPICS
Actions and scripting, How to

Views

2.8K

Likes

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

Adobe Community Professional , Jun 09, 2021 Jun 09, 2021
lyr.isBackgrounLayer = desc.getBoolean(stringIDToTypeID('background')) lyr.positionLocked = desc.getObjectValue(stringIDToTypeID('layerLocking')).getBoolean(stringIDToTypeID('protectPosition')) lyr.typename = ({'true': 'LayerSet', 'false': 'ArtLayer'})[!(typeIDToStringID(desc.getEnumerationValue(stringIDToTypeID('layerSection'))).split('Content').length-1)]

Likes

Translate

Translate
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

 

lyr.isBackgrounLayer = desc.getBoolean(stringIDToTypeID('background'))
lyr.positionLocked = desc.getObjectValue(stringIDToTypeID('layerLocking')).getBoolean(stringIDToTypeID('protectPosition'))
lyr.typename = ({'true': 'LayerSet', 'false': 'ArtLayer'})[!(typeIDToStringID(desc.getEnumerationValue(stringIDToTypeID('layerSection'))).split('Content').length-1)]

 

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

You can use this code to get more information about a selected Layer and use that to amend your Script. 

// based on code by michael l hale;
// 2012, 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);
checkDesc2 (layerDesc);
};
////// based on code by michael l hale //////
function checkDesc2 (theDesc) {
var c = theDesc.count;
var str = '';
for(var i=0;i<c;i++){ //enumerate descriptor's keys
	str = str + 'Key '+i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)+'\n';
	};
alert("desc\n\n"+str);
};
////// check //////
function getValues (theDesc, theNumber) {
switch (theDesc.getType(theDesc.getKey(theNumber))) {
case DescValueType.ALIASTYPE:
return theDesc.getPath(theDesc.getKey(theNumber));
break;
case DescValueType.BOOLEANTYPE:
return theDesc.getBoolean(theDesc.getKey(theNumber));
break;
case DescValueType.CLASSTYPE:
return theDesc.getClass(theDesc.getKey(theNumber));
break;
case DescValueType.DOUBLETYPE:
return theDesc.getDouble(theDesc.getKey(theNumber));
break;
case DescValueType.ENUMERATEDTYPE:
return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
break;
case DescValueType.INTEGERTYPE:
return theDesc.getInteger(theDesc.getKey(theNumber));
break;
case DescValueType.LISTTYPE:
return theDesc.getList(theDesc.getKey(theNumber));
break;
case DescValueType.OBJECTTYPE:
return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
break;
case DescValueType.RAWTYPE:
return theDesc.getReference(theDesc.getData(theNumber));
break;
case DescValueType.REFERENCETYPE:
return theDesc.getReference(theDesc.getKey(theNumber));
break;
case DescValueType.STRINGTYPE:
return theDesc.getString(theDesc.getKey(theNumber));
break;
case DescValueType.UNITDOUBLE:
return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
break;
default: 
break;
};
};

 

Likes

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 ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Thank you for your quick answers 🙂

 

@Kukurykus: maybe I didn't understand how to use your code in my script but Photoshop 6 tells me that sTT is not a function.

 

@c.pfaffenbichler: interesting but:

- Key 13 is "layerLocking: DescValueType.OBJECTTYPE
[ActionDescriptor]_layerLocking", even the layer is locked or not

- can't figure how to know if the layer is a LayerSet, or if its parent is a LayerSet.

 

As I really don't understand these deep codes, maybe another solution would be to have a reference to the current layer (at the end of the loop), so I could use:

lyr.isLayerSet = (layerRef.typename == 'LayerSet');
lyr.isLocked = layerRef.allLocked;

So, how could I have a layer reference from the initial code?

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Oh, I'm sorry, copy - paste failed. The mistake is corrected in my edited code 😉

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

See if you can see what you need from this script

layerInfo(activeDocument.activeLayer);

function layerInfo(layer) {
	try {
		if (layer.kind==LayerKind.TEXT) { 
			// Display some TextItem data
			var txtInfo  = "";
			txtInfo  = txtInfo + "\nLayerTextItemContents='" + layer.textItem.contents + "'";
			txtInfo  = txtInfo + "\nLayerTextItemFont='" + layer.textItem.font  + "'";
			txtInfo  = txtInfo + "\nLayerTextItemSize='" + layer.textItem.size + "'";
			txtInfo  = txtInfo + "\nLayerTextItemColor'" + layer.textItem.color.rgb.red + "," + layer.textItem.color.rgb.green + "," + layer.textItem.color.rgb.blue + "'";
			txtInfo  = txtInfo + "\nLayerTextItemDirection='" + layer.textItem.direction   + "'";
			txtInfo  = txtInfo + "\nLayerTextItemAntiAliasMethod='" + layer.textItem.antiAliasMethod  + "'";
			txtInfo  = txtInfo + "\nLayerTextItemPosition='" +layer.textItem.position + "'";	
			txtInfo  = txtInfo + "\nLayerTextItemKind='" + layer.textItem.kind  + "'";
			if (layer.textItem.kind==TextType.PARAGRAPHTEXT) { 
				txtInfo  = txtInfo + "\nLayerTextItemWidth='" + layer.textItem.width + "'"; 
				txtInfo  = txtInfo + "\nLayerTextItemHeight='" + layer.textItem.height + "'";			
				txtInfo  = txtInfo + "\nLayerTextItemTextComposer ='" + layer.textItem.textComposer  + "'";
			}
		}
		else {txtInfo="";}
	}
	catch(e) { 
		txtInfo= txtInfo + "\ntextItem " + e + ': on line ' + e.line
		layer.textItem.contents = layer.textItem.contents;
		layerInfo(layer);
	}
//	alert(txtInfo);
	alert("typename='" + layer.typename + "'"	
	+ "\nvisible='" + layer.visible + "'"		
	+ "\nlayerName='" + layer.name + "'" 	
	+ "\nisBackgroundLayer = " + layer.isBackgroundLayer	
	+ "\nlayerID='" + layer.id  + "'"
    + "\nitemIndex='" + layer.itemIndex + "'" 	
	+ "\nlayerKind='" + layer.kind + "'"
	+ "\nallLocked='" + layer.allLocked + "'"
	+ "\npixelsLocked = " + layer.pixelsLocked
	+ "\npositionLocked = " + layer.positionLocked 
	+ "\ntransparentPixelsLocked = " + layer.transparentPixelsLocked		
	+ "\nblendMode='" + layer.blendMode + "'"
	+ "\nopacity='" + layer.opacity + "'"
	+ "\nfillOpacity = " + layer.fillOpacity		
	+ "\nbounds='" + layer.bounds + "'"
	+ "\nboundsNoEffects='" + layer.boundsNoEffects + "'"
    + "\nlinkedLayers='" + layer.linkedLayers + "'"
	+ "\nparent='" + layer.parent + "'"	
	+ "\ngrouped = " + layer.grouped
	+ "\nlayerMaskDensity = " + layer.layerMaskDensity
	+ "\nlayerMaskFeather = " + layer.layerMaskFeather
	+ "\nvectorMaskDensity = " + layer.vectorMaskDensity 
	+ "\nvectorMaskFeather = " + layer.vectorMaskFeather	
	+ "\nxmpMetadata='" + obj_to_str(layer.xmpMetadata) + "'"	
	+ txtInfo
	);		
}
//Thanks to r-bin
function obj_to_str(obj){var str = ""; for (var p in obj) if(obj.hasOwnProperty(p))try{str+=p+"::"+obj[p]+"\n";}catch(e){};return str;}  
/*
TextItem Properties * indicates in the Alert
			//txtInfo  = txtInfo + "\nLayerTextItemLanguage='" + layer.textItem.language    + "'"
			//txtInfo  = txtInfo + "\nLayerTextItemFauxBold='" + layer.textItem.fauxBold   + "'"
			//txtInfo  = txtInfo + "\nLayerTextItemFauxItalic='" + layer.textItem.fauxItalic + "'"
			//txtInfo  = txtInfo + "\nLayerTextItemUnderline='" + layer.textItem.underline  + "'"
			//txtInfo  = txtInfo + "\nLayerTextItemCapitalization='" + layer.textItem.capitalization  + "'"


*antiAliasMethod 
autoKerning 
autoLeadingAmount 
baselineShift 
capitalization
*color 
*contents 
desiredGlyphScaling
desiredLetterScaling  
desiredWordScaling
*direction
fauxBold 
fauxItalic 
firstLineIndent 
*font
hangingPunctuation 
*height 
hyphenateAfterFirst 
hyphenateBeforeLast 
hyphenateCapitalWords 
hyphenateWordsLongerThan 
hyphenation 
hyphenationZone 
hyphenLimit 
justification
*kind 
language 
leading
leftIndent
ligatures
maximumGlyphScaling
maximumLetterScaling 
maximumWordScaling 
minimumGlyphScaling 
minimumLetterScaling 
minimumWordScaling 
noBreak 
oldStyle 
*parent
*position
rightIndent
*size
spaceAfter
spaceBefore
strikeThru 
*textComposer 
tracking 
typename
underline
useAutoLeading
verticalScale
warpBend
warpDirection
warpHorizontalDistortion 
warpStyle
warpVerticalDistortion
*width
*/

JJMack

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

»- Key 13 is "layerLocking: DescValueType.OBJECTTYPE
[ActionDescriptor]_layerLocking", even the layer is locked or not«

Yeah, one needs to »go deeper« when one wants to get the values from inside ObjectType – which @Kukurykus ’ line of code 

 

dsc.getObjectValue(sTT('layerLocking')).getBoolean(sTT('protectPosition'))

illustrates. 

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

I created the following script to help find layer based information when creating scripts that deal with layers:

 

/* https://community.adobe.com/t5/photoshop/could-you-select-all-layers-sequentially/m-p/11741392 */

#target photoshop

/////////// ACTIVE LAYER INSPECTOR v1.4 ///////////
/// Displays some info about the current layer ///

/* Name = Not unique */
/* itemIndex = Changes with layer addition/removal, Offset by -1 */
/* layer.id = Unique, Static */

try {
    var savedRuler = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    var doc = app.activeDocument;
    var docLayer = doc.activeLayer;
    var layerName = docLayer.name;
    var itemIndex = docLayer.itemIndex - 1;
    var layerID = docLayer.id;
    var typeName = docLayer.typename;
    var Kind = docLayer.kind;
    var bgLayer = docLayer.isBackgroundLayer;
    var Parent = docLayer.parent;

    /* https://community.adobe.com/t5/photoshop/find-out-the-size-and-position-of-an-object-in-a-layer/td-p/12057799 */
    var bounds = activeDocument.activeLayer.bounds;

    alert('ACTIVE LAYER INSPECTOR - v1.4' + '\r' + 'Layer Name: ' + layerName + '\r' + 'Layer Item Index #: ' + itemIndex + '\r' + 'Layer ID #: ' + layerID + '\r' + 'Layer Type: ' + typeName + '\r' + 'Layer Kind: ' + Kind + '\r' + 'Parent: ' + Parent + '\r' + 'isBackgroundLayer: ' + bgLayer + '\n' + 'Layer Bounds -' + '\r' + 'X: ' + bounds[0] + ', Y: ' + bounds[1] + '\n' + 'Width: ' + (bounds[2] - bounds[0]) + ', Height: ' + (bounds[3] - bounds[1]));
    app.preferences.rulerUnits = savedRuler;
}
catch (e) {
}

 

I didn't know about the other scripts posted above, so I'm keen to give them a look and perhaps borrow interesting bits!

Likes

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 ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Guys, you need to be very patient with me, because if I'm quite familiar with "pure" Javascript, I don't understand at all code like Kukurykus'one:

sTT = stringIDToTypeID;
(dsc = executeActionGet(ref)).getBoolean(sTT('background'))
dsc.getObjectValue(sTT('layerLocking')).getBoolean(sTT('protectPosition'))
!(typeIDToStringID(dsc.getEnumerationValue(sTT('layerSection'))).split('Content').length-1)

 

I mean, how can I include this code to my original script? How can I set the lyr object at the end of my script with this code? It's certainly a newbie question.

		lyr = {};
		lyr.index = tempIndex;
		lyr.id = desc.getInteger(stringIDToTypeID("layerID"));
		lyr.name = desc.getString(charIDToTypeID("Nm  "));
		///// lyr.isLayerSet = ???????
		///// lyr.isLocked = ???????
		///// lyr.isBackground = ???????
		lyrs.push(lyr);

 

Concerning the other posted scripts, they all seem to work with a passed layer reference... And I still don't know how to have a reference to a layer with my bloody original script 😞

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Probably the page did not refresh for you. Check my code again and you'll see it ideally fit to your script. I mean simply copy content of my post and replace with:

///// lyr.isLayerSet = ???????
///// lyr.isLocked = ???????
///// lyr.isBackground = ???????

 

Likes

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 ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Thnk you Kukurykus! 🙂

I didn't see you update, sorry.

 

On strange thing: it tells me the layer "lockedLayer" is unlock (see screen capture):

screen.jpg

Likes

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
Adobe Community Professional ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

You used 'movable' word that is not the same as locking everything. Change your line to:

 

lyr.allLocked = desc.getObjectValue(stringIDToTypeID('layerLocking')).getBoolean(stringIDToTypeID('protectAll'))

 

Likes

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 ,
Jun 09, 2021 Jun 09, 2021

Copy link to clipboard

Copied

Great!

Sorry to confuse you with "movable" (didn't know there was a difference).

 

Thanks all for your time and efforts 🙂

Likes

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 ,
Jun 12, 2021 Jun 12, 2021

Copy link to clipboard

Copied

@Kukurykus In order to know if a layer is inside a group or not, I tried to get the parent's name from the desc, using "PrNm" without success (I checked keyParentName exists in Photoshop CS6 from CS6 SDK). Any idea of how to retrieve this information?

I guess I should look "deeper" in one of the desc item, as c.pfaffenbichler said, but I don't know how.

Likes

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
Adobe Community Professional ,
Jun 12, 2021 Jun 12, 2021

Copy link to clipboard

Copied

Likes

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
Adobe Community Professional ,
Jun 12, 2021 Jun 12, 2021

Copy link to clipboard

Copied

quote

Getting layer's parent using ActionManager


By @Kukurykus

 

It seems that the code does not work correctly if the target layer is a folder.
 
Here, you can play around.

Likes

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
Adobe Community Professional ,
Jun 12, 2021 Jun 12, 2021

Copy link to clipboard

Copied

That's right, I noticed it too. But both of them wanted to know if a layer is inside of group 🙂

Likes

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
Adobe Community Professional ,
Jun 12, 2021 Jun 12, 2021

Copy link to clipboard

Copied

REM:

"parentName" and "parentIndex" refer to Actions.

The "parentName" for an Action is the name of its ActionSet.

This has nothing to do with layers.

Likes

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
Adobe Community Professional ,
Jun 12, 2021 Jun 12, 2021

Copy link to clipboard

Copied

Likes

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 ,
Jun 13, 2021 Jun 13, 2021

Copy link to clipboard

Copied

Thank you. Didn't think it was so complicated!

Likes

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
Adobe Community Professional ,
Jun 13, 2021 Jun 13, 2021

Copy link to clipboard

Copied

No, it's quite easy:

 

function lS() {
	return (s = typeIDToStringID(executeActionGet(ref)
	.getEnumerationValue(sTT(ls = 'layerSection')))
	.split(ls)[1].length - 7) + (!s ? 0 : 3)
}

sTT = stringIDToTypeID
bL = (lrs = activeDocument.layers)
[lrs.length - 1].isBackgroundLayer;
(ref = new ActionReference()).putEnumerated
(sTT('layer'), sTT('ordinal'), sTT('targetEnum'))
indx = (dsc = executeActionGet(ref)).getInteger(sTT('itemIndex')) - !!bL
lvl = lS() + 1; while(lvl && indx > 1) (ref = new ActionReference())
.putIndex(sTT('layer'), --indx), lvl += lS(); alert(!lvl)

 

Likes

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
Adobe Community Professional ,
Jun 13, 2021 Jun 13, 2021

Copy link to clipboard

Copied

1111.png

 

It's right?

 

Likes

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
Adobe Community Professional ,
Jun 13, 2021 Jun 13, 2021

Copy link to clipboard

Copied

Later I reminded myself to include background layer. The code is corrected. Check it again 🙂

Likes

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
Adobe Community Professional ,
Jun 13, 2021 Jun 13, 2021

Copy link to clipboard

Copied

2222.pngb69fd393bad18fd45b3128a5000f2b75.jpg

Likes

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
Adobe Community Professional ,
Jun 13, 2021 Jun 13, 2021

Copy link to clipboard

Copied

That's little oversight of undefined, as I forgot to use double exclamation mark before bL 😛

Likes

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