Copy link to clipboard
Copied
When I run this code on a "solid fill layer" or a "shape layer" I get the same result
alert(app.activeDocument.activeLayer.kind);
Result: LayerKind.SOLIDFILL
I assume that a regular solid fill layer and a shape layer are both "LayerKind.SOLIDFILL" under the hood. However, I need to perform different functions for a solid fill vs a shape layer. Is there a way to detect if the layer is a shape layer?
It appears that a shape layer has two properties that a solid fill layer doesn't have, but I haven't been able to figure out how to test if the properties exist on the layer.
Shape layers have these two extra properties:
pathBounds
AGMStrokeStyleInfo
Any information would be greatly appreciated
Action Manager uses a more detailed description of layer types:
const kAnySheet = 0;
const kPixelSheet = 1;
const kAdjustmentSheet = 2;
const kTextSheet = 3;
const kVectorSheet = 4;
const kSmartObjectSheet = 5;
const kVideoSheet = 6;
const kLayerGroupSheet = 7;
const k3DSheet = 8;
const kGradientSheet = 9;
const kPatternSheet = 10;
const kSolidColorSheet = 11;
const kBackgroundSheet = 12;
const kHiddenSectionBounder = 13;
try to use:
s2t = stringIDToTypeID;
(ref = new ActionReference()).putPrope
...
Copy link to clipboard
Copied
This seems to work. If there is a more elegant or more efficient way to do this please let me know.
var actionReference = new ActionReference();
actionReference.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var actionDescriptor = executeActionGet(actionReference);
isShapeLayer = false;
for (i = 0; i < actionDescriptor.count; i += 1) {
if (typeIDToStringID(actionDescriptor.getKey(i)) === "pathBounds") {
isShapeLayer = true;
}
}
alert(isShapeLayer);
Copy link to clipboard
Copied
Action Manager uses a more detailed description of layer types:
const kAnySheet = 0;
const kPixelSheet = 1;
const kAdjustmentSheet = 2;
const kTextSheet = 3;
const kVectorSheet = 4;
const kSmartObjectSheet = 5;
const kVideoSheet = 6;
const kLayerGroupSheet = 7;
const k3DSheet = 8;
const kGradientSheet = 9;
const kPatternSheet = 10;
const kSolidColorSheet = 11;
const kBackgroundSheet = 12;
const kHiddenSectionBounder = 13;
try to use:
s2t = stringIDToTypeID;
(ref = new ActionReference()).putProperty(s2t("property"), s2t("layerKind"))
ref.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"))
var activeLayerType = executeActionGet(ref).getInteger (s2t("layerKind"))
alert (activeLayerType)
Copy link to clipboard
Copied
Dmitry and Stephen,
Thanks for the replies! I really appreciate it.
Dmitry your script worked perfectly.
Copy link to clipboard
Copied
Yet another option:
// http://creativetuts.com/photoshop-script-determine-layer-kind/
// Photoshop Script
// "Determine Layer Kind"
// Script by Mehmet Şensoy
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
var layer = doc.activeLayer;// Save selected layer to variable:
function determinelayerkind (layer) {
if(layer.kind == LayerKind.TEXT) {layerkind = "Text Layer";return layerkind;} // Text Layer
else if(layer.kind == LayerKind.SOLIDFILL) {layerkind = "Shape Layer";return layerkind; } /* Shape Layer */
else if(layer.kind == LayerKind.BLACKANDWHITE) {layerkind = "Black and White adjustment layer";return layerkind; } /* Black and White */
else if(layer.kind == LayerKind.BRIGHTNESSCONTRAST) {layerkind = "Brightness contrast adjustment layer";return layerkind; } /* Brightness contrast adjustment layer */
else if(layer.kind == LayerKind.CHANNELMIXER) {layerkind = "Channel mixer adjustment layer";return layerkind; } /* Channel mixer adjustment layer */
else if(layer.kind == LayerKind.COLORBALANCE) {layerkind = "Color balance adjustment layer";return layerkind; } /* Color balance adjustment layer */
else if(layer.kind == LayerKind.CURVES) {layerkind = "Curves adjustment layer";return layerkind; } /* Curves adjustment layer */
else if(layer.kind == LayerKind.EXPOSURE) {layerkind = "Exposure layer";return layerkind; } /* Exposure layer */
else if(layer.kind == LayerKind.GRADIENTFILL) {layerkind = "Gradient fill";return layerkind; } /* Gradient fill */
else if(layer.kind == LayerKind.GRADIENTMAP) {layerkind = "Gradient map adjustment layer";return layerkind; } /* Gradient map adjustment layer */
else if(layer.kind == LayerKind.HUESATURATION) {layerkind = "Hue saturation adjustment layer";return layerkind; } /* Hue saturation adjustment layer */
else if(layer.kind == LayerKind.INVERSION) {layerkind = "Invert adjustment layer";return layerkind; } /* Invert adjustment layer */
else if(layer.kind == LayerKind.LAYER3D) {layerkind = "3D layer";return layerkind; } /* 3D layer */
else if(layer.kind == LayerKind.LEVELS) {layerkind = "Levels adjustment layer";return layerkind; } /* Levels adjustment layer */
else if(layer.kind == LayerKind.NORMAL) {layerkind = "Normal layer";return layerkind; } /* Normal Layer */
else if(layer.kind == LayerKind.PATTERNFILL) {layerkind = "Pattern fill layer";return layerkind; } /* Pattern fill layer */
else if(layer.kind == LayerKind.PHOTOFILTER) {layerkind = "Photo filter layer";return layerkind; } /* Photo filter layer */
else if(layer.kind == LayerKind.POSTERIZE) {layerkind = "Posterize adjustment layer";return layerkind; } /* Posterize adjustment layer */
else if(layer.kind == LayerKind.SELECTIVECOLOR) {layerkind = "Selective color adjustment layer.";return layerkind; } /* Selective color adjustment layer */
else if(layer.kind == LayerKind.SMARTOBJECT) {layerkind = "Smart object layer";return layerkind; } /* Smart object layer */
else if(layer.kind == LayerKind.THRESHOLD) {layerkind = "Threshold adjustment layer";return layerkind; } /* Threshold adjustment layer */
else if(layer.kind == LayerKind.VIBRANCE) {layerkind = "Vibrance layer";return layerkind; } /* Vibrance layer */
else if(layer.kind == LayerKind.VIDEO) {layerkind = "Video layer";return layerkind; } /* Video layer */
}
alert ("Current Layer is a " + determinelayerkind(layer));
EDIT: I just tested and this script reports a solid fill and a shape as both of a kind of "shape layer" with no distinction between them.
Copy link to clipboard
Copied
That's right, there is no property to distinguish between a shape or a solid color fill .... I need a solution.
Copy link to clipboard
Copied
The AM code script from @jazz-y (marked as the correct answer) would appear to correctly distinguish between shape (4) and color fill (11).
Are you having problems adapting that code into say an if/else or some other structure for conditional flow?
Copy link to clipboard
Copied
Sorry finally is solved. I used a sort of simmilar code based on that correct answer. Thanks!
Copy link to clipboard
Copied
That's right, there is no property to distinguish between a shape or a solid color fill .... I need a solution.
By @microbians com
Please provide a fuller description of your problem and, ideally, also a sample file or at least screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible.
Copy link to clipboard
Copied
I added a control to mantain visibility of the layer, just because the action excecution change it to visible always:
function isLayerShape(l) {
var activeDoc = app.activeDocument;
var currentVisiblity = l.visible;
activeDoc.activeLayer = l;
var s2t =stringIDToTypeID;
var r = new ActionReference();
r.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
var d = new ActionDescriptor();
d.putObject(s2t("object"), s2t("object"), executeActionGet(r));
var obj = executeAction(s2t("convertJSONdescriptor"), d).getString(s2t("json"));
l.visible=currentVisiblity;
return obj.indexOf("pathBounds")!=-1;
}
Copy link to clipboard
Copied
This is the most efficient way to check if the layer is a shape layer or not:
function IsLayerShape(layer) {
try {
if (!layer) {
layer = app.activeDocument.activeLayer;
}
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id);
var desc = executeActionGet(ref);
// Check if "pathBounds" key exists
if (desc.hasKey(stringIDToTypeID("pathBounds"))) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
}
Copy link to clipboard
Copied
This is the most efficient way to check if the layer is a shape layer or not:
function IsLayerShape(layer) { try { if (!layer) { layer = app.activeDocument.activeLayer; } var ref = new ActionReference(); ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); var desc = executeActionGet(ref); // Check if "pathBounds" key exists if (desc.hasKey(stringIDToTypeID("pathBounds"))) { return true; } else { return false; } } catch (e) { return false; } }
By @Flowgun
Thanksf for sharing!
I remember when I first started scripting, only being provided a named function wasn't enough, as I didn't know how to call the named function in an appropriate way. So for people new to scripting who need the whole code, here is the missing bit, the named fuction call (presuming an active layer):
alert( IsLayerShape(app.activeDocument.activeLayer) );
Or perhaps more useful with the returned boolean, in a conditional:
if ( IsLayerShape(app.activeDocument.activeLayer) ) {
alert("The active layer is a shape layer.");
// Do something here...
} else {
alert("The active layer is NOT a shape layer.");
// Do something else...
}
That being said, I personally prefer to test/check whether a layer is explicitly a solid fill or shape layer:
if (isShapeLayerAM(app.activeDocument.activeLayer)) {
alert("The selected layer is a shape layer.");
} else if (isSolidColorSheeetAM(app.activeDocument.activeLayer)) {
alert("The selected layer is a solid color layer.");
} else {
alert("The selected layer is neither a shape layer nor a solid color layer.")
}
function isShapeLayerAM(layer) {
try {
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id);
var layerDesc = executeActionGet(ref);
return layerDesc.getInteger(stringIDToTypeID("layerKind")) === 4;
} catch (e) {
return false;
}
}
function isSolidColorSheeetAM(layer) {
try {
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id);
var layerDesc = executeActionGet(ref);
return layerDesc.getInteger(stringIDToTypeID("layerKind")) === 11;
} catch (e) {
return false;
}
}
Copy link to clipboard
Copied
it's easy to add a conditional to check if its kind matches being a solid fill/Shape layer while my function returns 0. In that case, it's a solid fill layer.
I personally don't code directly in JSX but I use COM integration so it's not the same for everyone and that's why I only provided the naked function. I also encountered the problems you're talking about before, but I think that's no longer a relevant problem in the age of vibe-coding as anyone can throw the code into chatGPT and get what they want.
Copy link to clipboard
Copied
You are indeed correct that it is much eaiser for casual users to code today than it was 2-3 years ago.
Copy link to clipboard
Copied
I updated my code to look something like this for checking if it's a shape layer (I'm coding in Autohotkey and I used chatGPT to convert to JSX, so it's not tested). Previously, I added more checks to the function I posted above, but this is a quicker way as it uses Action Manager and works with IDs instead of requiring objects or DOM.
function PS_IsShapeLayer(layerID) {
var psApp = app; // Photoshop.Application
var ref = new ActionReference();
// Use active layer if no layerID is given
if (layerID === undefined || layerID === null) {
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
} else if (typeof layerID === "object" && layerID.hasOwnProperty("id")) {
// layerID is actually a Layer object
ref.putIdentifier(charIDToTypeID("Lyr "), layerID.id);
} else {
ref.putIdentifier(charIDToTypeID("Lyr "), layerID);
}
try {
var layerKindVal = executeActionGet(ref).getInteger(stringIDToTypeID("layerKind"));
return layerKindVal === 4; // 4 = Vector Sheet / Shape Layer
} catch (e) {
return false;
}
}
Find more inspiration, events, and resources on the new Adobe Community
Explore Now