Copy link to clipboard
Copied
how to copy multiple layer names at once.
I have multiple layers and groups. I need to copy all layer names and group names at once and want to paste it into another place like a notepad or Excel
Kindly suggest a solution
There are many scripts for this if you search the forum.
Is this only for top-level layers/layer groups?
Or do you also have groups and require the content of those groups as well?
Copy link to clipboard
Copied
There are many scripts for this if you search the forum.
Is this only for top-level layers/layer groups?
Or do you also have groups and require the content of those groups as well?
Copy link to clipboard
Copied
Thank you for your responce. layers + group name + content of those groups
Copy link to clipboard
Copied
Surely you are not the first to ask such a question, I'd start with a forum or internet search...
Copy link to clipboard
Copied
This isn't easy for me... I know that for others this isn't a challenge.
I have come up with the following result from hacking together some other scripts:
What I don't like about it:
1) It is in the reverse order compared to the layer panel
2) The child layers inside the parent layer set should be indented with space or something
Perhaps somebody else could improve it?
if (!documents.length) {
alert('There are no documents open!');
} else {
// Log text file platform specific LF options
var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
if (os === "mac") {
layerListLF = "Unix";
} else {
layerListLF = "Windows";
}
// Create the preference file
var layerList = new File('~/Desktop/_LayerList.txt');
var dateTime = new Date().toLocaleString();
if (layerList.exists)
layerList.remove();
// Call the main function
processAllLayersAndSets(app.activeDocument);
}
function processAllLayersAndSets(obj) {
// Process Layers
for (var i = obj.layers.length - 1; 0 <= i; i--) {
app.activeDocument.activeLayer = obj.layers[i];
layerList.open("a");
layerList.encoding = "UTF-8";
layerList.lineFeed = layerListLF;
layerList.writeln(activeDocument.activeLayer.name);
layerList.close();
}
// Process Layer Set Layers
for (var j = obj.layerSets.length - 1; 0 <= j; j--) {
processAllLayersAndSets(obj.layerSets[j]);
}
}
EDIT – Here's an updated version with the previous shortcomings corrected:
/*
Layer List Text File Creator.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-copy-multiple-layer-names/m-p/13118781#M662792
*/
if (!documents.length) {
alert('There are no documents open!');
} else {
// Log text file platform specific LF options
var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
var layerListLF = os === "mac" ? "Unix" : "Windows";
// Create the preference file
var layerList = new File('~/Desktop/_LayerList.txt');
if (layerList.exists) layerList.remove();
// Call the main function
processAllLayersAndSets(app.activeDocument, 0); // Start with depth 0
}
function processAllLayersAndSets(obj, depth) {
// Process layers in top-to-bottom order
for (var i = 0; i < obj.layers.length; i++) {
var currentLayer = obj.layers[i];
app.activeDocument.activeLayer = currentLayer;
// Create indentation based on the depth
var indentation = new Array(depth + 1).join(" "); // 3 spaces per depth level
//var indentation = new Array(depth + 1).join("\t"); // Tab character
// Write layer name with indentation
layerList.open("a");
layerList.encoding = "UTF-8";
layerList.lineFeed = layerListLF;
layerList.writeln(indentation + currentLayer.name);
layerList.close();
// If the layer is a group, process its layers recursively with increased depth
if (currentLayer.typename === "LayerSet") {
processAllLayersAndSets(currentLayer, depth + 1);
}
}
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I have created a new script, combining the layer name to text file features from my earlier script, with various features from my "Active Layer Inspector" script.
/*
Layer List CSV File Creator scriptUI GUI v1-0.jsx
v1.0 - 9th April 2025
v1.1 - 2nd May 2025, Updated to force ruler units to pixels
Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-copy-multiple-layer-names/m-p/13118781#U15263262
*/
#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!');
// Restore original ruler units
app.preferences.rulerUnits = originalRulerUnits;
exit();
}
// Get the active document name sans extension
var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
// Create the main window
var dlg = new Window('dialog', 'Layer List CSV File Creator (v1.1)');
dlg.orientation = 'column';
dlg.alignChildren = 'fill';
dlg.preferredSize.width = 470;
// Panel/Group for file selection
var filePanel = dlg.add('panel', undefined, 'Save Location:');
filePanel.orientation = 'row';
filePanel.alignChildren = 'fill';
var browseButton = filePanel.add('button', undefined, 'Browse...');
// edittext or statictext for file path
var filePath = filePanel.add('edittext', undefined, '~/Desktop/' + docName + '.csv', { truncate: 'middle' });
filePath.characters = 30;
browseButton.onClick = function () {
var defaultFileName = docName + '.csv';
// Create a File object with the default path and filename
var defaultFile = new File("~/Desktop/" + defaultFileName);
var file = defaultFile.saveDlg('Save CSV File As...', '*.csv');
if (file) filePath.text = file.fsName;
};
// Panel/Group for layer properties selection
var layerPropertiesPanel = dlg.add('panel', undefined, 'Select Layer Properties to Include:');
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');
// Panel/Group for exclusion options
var exclusionPanel = dlg.add('panel', undefined, 'Layer Exclusion Options:');
exclusionPanel.orientation = 'column';
exclusionPanel.alignChildren = 'left';
var excludeInvisibleCB = exclusionPanel.add('checkbox', undefined, 'Exclude Invisible Layers');
excludeInvisibleCB.value = false; // Default state
// Event handler to disable visibility checkbox when exclude invisible is checked
excludeInvisibleCB.onClick = function () {
visibilityCB.enabled = !excludeInvisibleCB.value;
// If the checkbox is being disabled, also uncheck it
if (!visibilityCB.enabled) {
visibilityCB.value = false;
} else {
// If we're enabling the visibility checkbox, also check it
visibilityCB.value = true;
}
};
// Checkbox for excluding adjustment layers
var excludeAdjustmentCB = exclusionPanel.add('checkbox', undefined, 'Exclude Adjustment Layers');
excludeAdjustmentCB.value = false; // Default state
// Check all checkboxes by default
layerNameCB.value = true;
visibilityCB.value = true;
typeCB.value = true;
layerKindCB.value = true;
layerKindAMCB.value = true; // New checkbox default
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;
if (visibilityCB.enabled) {
visibilityCB.value = true;
}
typeCB.value = true;
layerKindCB.value = true;
layerKindAMCB.value = true; // Added
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; // Added
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 (!documents.length) {
alert('There are no documents open!');
} else {
var csvFile = new File(filePath.text);
if (csvFile.exists) csvFile.remove();
// Create array of selected columns
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 column to include in the CSV file.');
return;
}
csvFile.open("w");
csvFile.encoding = "UTF-8";
csvFile.lineFeed = "Unix";
csvFile.writeln(columns.join(","));
csvFile.close();
processAllLayersAndSets(app.activeDocument, 0, csvFile, columnProperties, excludeInvisibleCB.value, excludeAdjustmentCB.value, null);
alert('CSV file created successfully!');
}
dlg.close();
};
cancelButton.onClick = function () {
dlg.close();
};
dlg.show();
dlg.center();
// Restore original ruler units
app.preferences.rulerUnits = originalRulerUnits;
function processAllLayersAndSets(obj, depth, csvFile, columnProperties, excludeInvisible, excludeAdjustment, parentName) {
for (var i = 0; i < obj.layers.length; i++) {
var currentLayer = obj.layers[i];
if (excludeInvisible && !currentLayer.visible) {
continue;
}
var isAdjustment = isAdjustmentLayer(currentLayer);
if (excludeAdjustment && isAdjustment) {
continue;
}
var indentation = new Array(depth + 1).join(" ");
var layerName = indentation + currentLayer.name;
var visibility = currentLayer.visible;
var type = currentLayer.typename;
var layerKind = getLayerKind(currentLayer);
var layerKindAM = getLayerKindAM(currentLayer);
var opacity = Math.round(currentLayer.opacity);
var blendMode = currentLayer.blendMode;
var hasMask = hasLayerMask(currentLayer);
var layerId = currentLayer.id;
var parent = parentName;
var upperLeftX = "";
var upperLeftY = "";
var width = "";
var height = "";
// For groups & adjustment layers, leave width and height empty
// For other layers, calculate their dimensions
if (type !== "LayerSet" && !isAdjustment) {
if (currentLayer.isBackgroundLayer) {
upperLeftX = 0;
upperLeftY = 0;
var bounds = currentLayer.bounds;
width = parseInt(bounds[2] - bounds[0]);
height = parseInt(bounds[3] - bounds[1]);
} else {
var bounds = currentLayer.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 = "";
}
}
// Create row with only selected columns
var rowData = [];
for (var j = 0; j < columnProperties.length; j++) {
var prop = columnProperties[j];
rowData.push(eval(prop));
}
csvFile.open("a");
csvFile.encoding = "UTF-8";
csvFile.lineFeed = "Unix";
csvFile.writeln(rowData.join(","));
csvFile.close();
if (currentLayer.typename === "LayerSet") {
processAllLayersAndSets(currentLayer, depth + 1, csvFile, columnProperties, excludeInvisible, excludeAdjustment, currentLayer.name);
}
}
}
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"));
// First, handle non-adjustment layers via AM code, map the kindValue to the appropriate string
var kindString = "";
switch (kindValue) {
case 0: kindString = "LayerKind.UNDEFINED"; break; // No mapping in DOM
case 1: kindString = "LayerKind.NORMAL"; break; // Pixel layer
case 3: kindString = "LayerKind.TEXT"; break; // Text layer
case 4: kindString = "LayerKind.SHAPELAYER"; break; // Shape layer
case 5: kindString = "LayerKind.SMARTOBJECT"; break; // Smart Object
case 6: kindString = "LayerKind.VIDEO"; break; // Video layer
case 7: kindString = "LayerKind.LAYERSECTION"; break; // Layer Group
case 8: kindString = "LayerKind.LAYER3D"; break; // 3D layer
case 9: kindString = "LayerKind.GRADIENTFILL"; break; // Gradient Fill
case 10: kindString = "LayerKind.PATTERNFILL"; break; // Pattern Fill
case 11: kindString = "LayerKind.SOLIDFILL"; break; // Solid Fill
case 12: kindString = "LayerKind.BACKGROUND"; break; // Background layer
case 13: kindString = "LayerKind.HIDDENSECTIONBOUNDER"; break; // Hidden Section Bounder
case 14: kindString = "LayerKind.VECTOR"; break; // Vector layer
}
// If it's an adjustment layer (kindValue === 2), determine the specific type
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";
}
}
// Append "isBackground" if the layer is a background layer
if (layer.isBackgroundLayer) {
kindString += " isBackground";
}
return kindString;
}
return "LayerKind.UNKNOWN";
} catch (e) {
return "Error: " + e.message;
}
}
function getLayerKindAM(layer) {
try {
// Get the layer kind using Action Manager
var s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('layerKind'));
r.putIdentifier(s2t('layer'), layer.id); // Use layer ID instead of targetEnum
var layerKind = executeActionGet(r).getInteger(s2t('layerKind'));
// Map the layer kind to the appropriate string
var kindStringAM = "";
if (layerKind === 0) {
kindStringAM = "kAnySheet";
} else if (layerKind === 1) {
kindStringAM = "kPixelSheet";
} else if (layerKind === 2) {
// For adjustment layers, get the specific adjustment type
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 + ")";
}
// Append "isBackground" if the layer is a background layer
if (layer.isBackgroundLayer) {
kindStringAM += " (isBackground = true)";
}
return kindStringAM;
} catch (e) {
return "Error: " + e.message;
}
}
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Find more inspiration, events, and resources on the new Adobe Community
Explore Now