Last active
June 21, 2025 08:23
-
-
Save MarshySwamp/ef345ef3dec60a843465347ee6fcae2f to your computer and use it in GitHub Desktop.
Report on the active layer name, layer itemIndex & layer id value
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Active Layer Inspector.jsx | |
Stephen Marsh | |
v1.9 - 21st June 2025 | |
https://community.adobe.com/t5/photoshop-ecosystem-discussions/could-you-select-all-layers-sequentially/td-p/11732510/page/3#U12078337 | |
https://gist.githubusercontent.com/MarshySwamp/ef345ef3dec60a843465347ee6fcae2f/raw/3f4ebef778bbc841f5c27f2744b79b6044145fbc/Active%2520Layer%2520Inspector.jsx | |
Displays info about the current layer, useful for script development and debugging | |
Related script for all layers: | |
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-copy-multiple-layer-names/m-p/13118781#U15263262 | |
*/ | |
// name = Not unique | |
// itemIndex = Changes with layer addition/removal, Background layer index starts at 0 - no Background starts at 1 | |
// layer.id = Unique, static and more useful | |
// Bounds: | |
// + - - - - - - - [1] - - - - - - - + | |
// | | | |
// | | | |
// [0] [2] | |
// | | | |
// | | | |
// + - - - - - - - [3] - - - - - - - + | |
#target photoshop | |
// Save the original ruler units to restore later | |
var originalRulerUnits = app.preferences.rulerUnits; | |
// Set the ruler units to pixels | |
app.preferences.rulerUnits = Units.PIXELS; | |
// Check if there are open documents | |
if (app.documents.length === 0) { | |
alert('Please open a document before running this script!'); | |
app.preferences.rulerUnits = originalRulerUnits; | |
exit(); | |
} | |
// Create the main window | |
var dlg = new Window('dialog', 'Active Layer Inspector (v1.9)'); | |
dlg.orientation = 'column'; | |
dlg.alignChildren = 'fill'; | |
dlg.preferredSize.width = 470; | |
// Panel/Group for layer properties selection | |
var layerPropertiesPanel = dlg.add('panel', undefined, 'Select Layer Properties to Display:'); | |
layerPropertiesPanel.orientation = 'column'; | |
layerPropertiesPanel.alignChildren = 'left'; | |
// Create layer properties selection checkboxes | |
var layerNameCB = layerPropertiesPanel.add('checkbox', undefined, 'Layer Name'); | |
var visibilityCB = layerPropertiesPanel.add('checkbox', undefined, 'Visibility'); | |
var typeCB = layerPropertiesPanel.add('checkbox', undefined, 'Type'); | |
var layerKindCB = layerPropertiesPanel.add('checkbox', undefined, 'Kind (DOM)'); | |
var layerKindAMCB = layerPropertiesPanel.add('checkbox', undefined, 'Kind (AM)'); | |
var opacityCB = layerPropertiesPanel.add('checkbox', undefined, 'Opacity'); | |
var blendModeCB = layerPropertiesPanel.add('checkbox', undefined, 'Blend Mode'); | |
var maskCB = layerPropertiesPanel.add('checkbox', undefined, 'Mask'); | |
var layerIdCB = layerPropertiesPanel.add('checkbox', undefined, 'Layer ID'); | |
var parentCB = layerPropertiesPanel.add('checkbox', undefined, 'Parent'); | |
// Create position & dimension checkboxes in a sub-panel | |
var dimensionPanel = layerPropertiesPanel.add('panel', undefined, 'Position & Dimensions:'); | |
dimensionPanel.orientation = 'column'; | |
dimensionPanel.alignChildren = 'left'; | |
var upperLeftXCB = dimensionPanel.add('checkbox', undefined, 'Upper Left X'); | |
var upperLeftYCB = dimensionPanel.add('checkbox', undefined, 'Upper Left Y'); | |
var widthCB = dimensionPanel.add('checkbox', undefined, 'Width'); | |
var heightCB = dimensionPanel.add('checkbox', undefined, 'Height'); | |
// Check all checkboxes by default | |
layerNameCB.value = true; | |
visibilityCB.value = true; | |
typeCB.value = true; | |
layerKindCB.value = true; | |
layerKindAMCB.value = true; | |
opacityCB.value = true; | |
blendModeCB.value = true; | |
maskCB.value = true; | |
layerIdCB.value = true; | |
parentCB.value = true; | |
upperLeftXCB.value = true; | |
upperLeftYCB.value = true; | |
widthCB.value = true; | |
heightCB.value = true; | |
// Button to select/deselect all columns | |
var selectAllGroup = layerPropertiesPanel.add('group'); | |
selectAllGroup.orientation = 'row'; | |
var selectAllButton = selectAllGroup.add('button', undefined, 'Select All'); | |
var deselectAllButton = selectAllGroup.add('button', undefined, 'Deselect All'); | |
selectAllButton.onClick = function () { | |
layerNameCB.value = true; | |
visibilityCB.value = true; | |
typeCB.value = true; | |
layerKindCB.value = true; | |
layerKindAMCB.value = true; | |
opacityCB.value = true; | |
blendModeCB.value = true; | |
maskCB.value = true; | |
layerIdCB.value = true; | |
parentCB.value = true; | |
upperLeftXCB.value = true; | |
upperLeftYCB.value = true; | |
widthCB.value = true; | |
heightCB.value = true; | |
}; | |
deselectAllButton.onClick = function () { | |
layerNameCB.value = false; | |
visibilityCB.value = false; | |
typeCB.value = false; | |
layerKindCB.value = false; | |
layerKindAMCB.value = false; | |
opacityCB.value = false; | |
blendModeCB.value = false; | |
maskCB.value = false; | |
layerIdCB.value = false; | |
parentCB.value = false; | |
upperLeftXCB.value = false; | |
upperLeftYCB.value = false; | |
widthCB.value = false; | |
heightCB.value = false; | |
}; | |
// Cancel and OK buttons | |
var buttonGroup = dlg.add('group'); | |
buttonGroup.orientation = 'row'; | |
buttonGroup.alignment = 'right'; | |
var cancelButton = buttonGroup.add('button', undefined, 'Cancel'); | |
var okButton = buttonGroup.add('button', undefined, 'OK'); | |
okButton.onClick = function () { | |
if (!app.documents.length) { | |
alert('There are no documents open!'); | |
return; | |
} | |
var activeLayer = app.activeDocument.activeLayer; | |
// Create array of selected columns/properties and their labels | |
var columns = []; | |
var columnProperties = []; | |
if (layerNameCB.value) { columns.push("Layer Name"); columnProperties.push("layerName"); } | |
if (visibilityCB.value) { columns.push("Visibility"); columnProperties.push("visibility"); } | |
if (typeCB.value) { columns.push("Type"); columnProperties.push("type"); } | |
if (layerKindCB.value) { columns.push("Kind (DOM)"); columnProperties.push("layerKind"); } | |
if (layerKindAMCB.value) { columns.push("Kind (AM)"); columnProperties.push("layerKindAM"); } | |
if (opacityCB.value) { columns.push("Opacity"); columnProperties.push("opacity"); } | |
if (blendModeCB.value) { columns.push("Blend Mode"); columnProperties.push("blendMode"); } | |
if (maskCB.value) { columns.push("Mask"); columnProperties.push("hasMask"); } | |
if (layerIdCB.value) { columns.push("Layer ID"); columnProperties.push("layerId"); } | |
if (parentCB.value) { columns.push("Parent"); columnProperties.push("parent"); } | |
if (upperLeftXCB.value) { columns.push("Upper Left X"); columnProperties.push("upperLeftX"); } | |
if (upperLeftYCB.value) { columns.push("Upper Left Y"); columnProperties.push("upperLeftY"); } | |
if (widthCB.value) { columns.push("Width"); columnProperties.push("width"); } | |
if (heightCB.value) { columns.push("Height"); columnProperties.push("height"); } | |
// At least one column must be selected | |
if (columns.length === 0) { | |
alert('Please select at least one property to display.'); | |
return; | |
} | |
// Collect active layer info | |
var info = getActiveLayerInfo(activeLayer, columnProperties); | |
// Prepare alert string | |
var result = "Active Layer Info:\n"; | |
for (var i = 0; i < columns.length; i++) { | |
result += columns[i] + ": " + info[i] + "\n"; | |
} | |
alert(result); | |
dlg.close(); | |
}; | |
cancelButton.onClick = function () { | |
dlg.close(); | |
}; | |
dlg.center(); | |
dlg.show(); | |
// Restore original ruler units | |
app.preferences.rulerUnits = originalRulerUnits; | |
// Helper: get info for the active layer | |
function getActiveLayerInfo(layer, columnProperties) { | |
// Parent name | |
var parent = ""; | |
try { | |
if (layer.parent && layer.parent.typename === "LayerSet") { | |
parent = layer.parent.name; | |
} | |
} catch (e) { parent = ""; } | |
var isAdjustment = isAdjustmentLayer(layer); | |
var type = layer.typename; | |
// Default position/dimensions | |
var upperLeftX = ""; | |
var upperLeftY = ""; | |
var width = ""; | |
var height = ""; | |
// For groups & adjustment layers, leave width and height empty | |
if (type !== "LayerSet" && !isAdjustment) { | |
if (layer.isBackgroundLayer) { | |
upperLeftX = 0; | |
upperLeftY = 0; | |
var bounds = layer.bounds; | |
width = parseInt(bounds[2] - bounds[0]); | |
height = parseInt(bounds[3] - bounds[1]); | |
} else { | |
var bounds = layer.bounds; | |
upperLeftX = parseInt(bounds[0]); | |
upperLeftY = parseInt(bounds[1]); | |
width = parseInt(bounds[2] - bounds[0]); | |
height = parseInt(bounds[3] - bounds[1]); | |
if (upperLeftX === 0) upperLeftX = ""; | |
if (upperLeftY === 0) upperLeftY = ""; | |
if (width === 0) width = ""; | |
if (height === 0) height = ""; | |
} | |
} | |
// Map property keys to values | |
var vals = { | |
layerName: layer.name, | |
visibility: layer.visible, | |
type: type, | |
layerKind: getLayerKind(layer), | |
layerKindAM: getLayerKindAM(layer), | |
opacity: Math.round(layer.opacity), | |
blendMode: layer.blendMode, | |
hasMask: hasLayerMask(layer), | |
layerId: layer.id, | |
parent: parent, | |
upperLeftX: upperLeftX, | |
upperLeftY: upperLeftY, | |
width: width, | |
height: height | |
}; | |
// Build array of only selected values | |
var infoArr = []; | |
for (var i = 0; i < columnProperties.length; i++) { | |
infoArr.push(vals[columnProperties[i]]); | |
} | |
return infoArr; | |
} | |
function hasLayerMask(layer) { | |
try { | |
var ref = new ActionReference(); | |
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); | |
var layerDesc = executeActionGet(ref); | |
return layerDesc.hasKey(stringIDToTypeID("userMaskEnabled")) && | |
layerDesc.getBoolean(stringIDToTypeID("userMaskEnabled")); | |
} catch (e) { | |
return false; | |
} | |
} | |
function isAdjustmentLayer(layer) { | |
try { | |
var ref = new ActionReference(); | |
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); | |
var layerDesc = executeActionGet(ref); | |
if (layerDesc.hasKey(stringIDToTypeID("layerKind"))) { | |
var layerKind = layerDesc.getInteger(stringIDToTypeID("layerKind")); | |
return layerKind === 2; | |
} | |
return false; | |
} catch (e) { | |
return false; | |
} | |
} | |
function getLayerKind(layer) { | |
try { | |
var ref = new ActionReference(); | |
ref.putIdentifier(charIDToTypeID("Lyr "), layer.id); | |
var layerDesc = executeActionGet(ref); | |
if (layerDesc.hasKey(stringIDToTypeID("layerKind"))) { | |
var kindValue = layerDesc.getInteger(stringIDToTypeID("layerKind")); | |
var kindString = ""; | |
switch (kindValue) { | |
case 0: kindString = "LayerKind.UNDEFINED"; break; | |
case 1: kindString = "LayerKind.NORMAL"; break; | |
case 3: kindString = "LayerKind.TEXT"; break; | |
case 4: kindString = "LayerKind.SHAPELAYER"; break; | |
case 5: kindString = "LayerKind.SMARTOBJECT"; break; | |
case 6: kindString = "LayerKind.VIDEO"; break; | |
case 7: kindString = "LayerKind.LAYERSECTION"; break; | |
case 8: kindString = "LayerKind.LAYER3D"; break; | |
case 9: kindString = "LayerKind.GRADIENTFILL"; break; | |
case 10: kindString = "LayerKind.PATTERNFILL"; break; | |
case 11: kindString = "LayerKind.SOLIDFILL"; break; | |
case 12: kindString = "LayerKind.BACKGROUND"; break; | |
case 13: kindString = "LayerKind.HIDDENSECTIONBOUNDER"; break; | |
case 14: kindString = "LayerKind.VECTOR"; break; | |
} | |
if (kindValue === 2) { | |
var adjustmentDesc = layerDesc.getList(stringIDToTypeID("adjustment")); | |
if (adjustmentDesc.count > 0) { | |
var adjustmentType = adjustmentDesc.getObjectType(0); | |
switch (adjustmentType) { | |
case stringIDToTypeID("levels"): kindString = "LayerKind.LEVELS (Adjustment Layer)"; break; | |
case stringIDToTypeID("curves"): kindString = "LayerKind.CURVES (Adjustment Layer)"; break; | |
case stringIDToTypeID("colorBalance"): kindString = "LayerKind.COLORBALANCE (Adjustment Layer)"; break; | |
case stringIDToTypeID("brightnessContrast"): kindString = "LayerKind.BRIGHTNESSCONTRAST (Adjustment Layer)"; break; | |
case stringIDToTypeID("hueSaturation"): kindString = "LayerKind.HUESATURATION (Adjustment Layer)"; break; | |
case stringIDToTypeID("selectiveColor"): kindString = "LayerKind.SELECTIVECOLOR (Adjustment Layer)"; break; | |
case stringIDToTypeID("channelMixer"): kindString = "LayerKind.CHANNELMIXER (Adjustment Layer)"; break; | |
case stringIDToTypeID("gradientMapClass"): kindString = "LayerKind.GRADIENTMAP (Adjustment Layer)"; break; | |
case stringIDToTypeID("invert"): kindString = "LayerKind.INVERSION (Adjustment Layer)"; break; | |
case stringIDToTypeID("posterize"): kindString = "LayerKind.POSTERIZE (Adjustment Layer)"; break; | |
case stringIDToTypeID("thresholdClassEvent"): kindString = "LayerKind.THRESHOLD (Adjustment Layer)"; break; | |
case stringIDToTypeID("blackWhite"): kindString = "LayerKind.BLACKWHITE (Adjustment Layer)"; break; | |
case stringIDToTypeID("vibrance"): kindString = "LayerKind.VIBRANCE (Adjustment Layer)"; break; | |
case stringIDToTypeID("colorLookup"): kindString = "LayerKind.COLORLOOKUP (Adjustment Layer)"; break; | |
case stringIDToTypeID("exposure"): kindString = "LayerKind.EXPOSURE (Adjustment Layer)"; break; | |
case stringIDToTypeID("photoFilter"): kindString = "LayerKind.PHOTOFILTER (Adjustment Layer)"; break; | |
case stringIDToTypeID("blackAndWhite"): kindString = "LayerKind.BLACKANDWHITE (Adjustment Layer)"; break; | |
default: kindString = "Unknown Adjustment Layer (" + typeIDToStringID(adjustmentType) + ")"; | |
} | |
} else { | |
kindString = "Unknown Adjustment Layer"; | |
} | |
} | |
if (layer.isBackgroundLayer) { | |
kindString += " isBackground"; | |
} | |
return kindString; | |
} | |
return "LayerKind.UNKNOWN"; | |
} catch (e) { | |
return "Error: " + e.message; | |
} | |
} | |
function getLayerKindAM(layer) { | |
try { | |
var s2t = stringIDToTypeID; | |
var r = new ActionReference(); | |
r.putProperty(s2t('property'), s2t('layerKind')); | |
r.putIdentifier(s2t('layer'), layer.id); | |
var layerKind = executeActionGet(r).getInteger(s2t('layerKind')); | |
var kindStringAM = ""; | |
if (layerKind === 0) { | |
kindStringAM = "kAnySheet"; | |
} else if (layerKind === 1) { | |
kindStringAM = "kPixelSheet"; | |
} else if (layerKind === 2) { | |
var rAdj = new ActionReference(); | |
rAdj.putProperty(s2t('property'), s2t('adjustment')); | |
rAdj.putIdentifier(s2t('layer'), layer.id); | |
var adjustmentList = executeActionGet(rAdj).getList(s2t('adjustment')); | |
if (adjustmentList.count > 0) { | |
var adjustmentType = typeIDToStringID(adjustmentList.getObjectType(0)); | |
kindStringAM = "kAdjustmentSheet (" + adjustmentType + ")"; | |
} else { | |
kindStringAM = "kAdjustmentSheet (Unknown)"; | |
} | |
} else if (layerKind === 3) { | |
kindStringAM = "kTextSheet"; | |
} else if (layerKind === 4) { | |
kindStringAM = "kVectorSheet"; | |
} else if (layerKind === 5) { | |
kindStringAM = "kSmartObjectSheet"; | |
} else if (layerKind === 6) { | |
kindStringAM = "kVideoSheet"; | |
} else if (layerKind === 7) { | |
kindStringAM = "kLayerGroupSheet"; | |
} else if (layerKind === 8) { | |
kindStringAM = "k3DSheet"; | |
} else if (layerKind === 9) { | |
kindStringAM = "kGradientSheet"; | |
} else if (layerKind === 10) { | |
kindStringAM = "kPatternSheet"; | |
} else if (layerKind === 11) { | |
kindStringAM = "kSolidColorSheet"; | |
} else if (layerKind === 12) { | |
kindStringAM = "kBackgroundSheet"; | |
} else if (layerKind === 13) { | |
kindStringAM = "kHiddenSectionBounder"; | |
} else { | |
kindStringAM = "Unknown AM Kind (" + layerKind + ")"; | |
} | |
if (layer.isBackgroundLayer) { | |
kindStringAM += " (isBackground = true)"; | |
} | |
return kindStringAM; | |
} catch (e) { | |
return "Error: " + e.message; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment