Hi,
I've been asked to retrieve the Layers' bounds in a document - which is somehow easy also because there already are few examples in the forums.
The fastest approach uses ActionManager (AM) to get the "flat" list of all layers, then again via AM it gets the bounds or whatever you need.
In my own case the layers are *highly* nested in layerSets, and the requirement is to build a URL-like list of them:
DAY/touring
TopLeft (198 px, 23 px); BottomRight (282 px, 40 px); Width (84 px); Height (17 px); Center (240 px, 31.5 px);
DAY/WARNING e SERVICE/alert generico/alert generico
TopLeft (102 px, 144 px); BottomRight (124 px, 164 px); Width (22 px); Height (20 px); Center (113 px, 154 px);
DAY/WARNING e SERVICE/alert generico/Rettangolo arrotondato
TopLeft (99 px, 140 px); BottomRight (127 px, 168 px); Width (28 px); Height (28 px); Center (113 px, 154 px);
where the name after the last "/" is the layerName, everything before is nested layerSet names.
I've been able to get there using a recursive function:
function printData(lay, layPath) { logFile.writeln( layPath + lay.name + "\n" + "TopLeft (" + lay.bounds[0] + ", " + lay.bounds[1] + "); BottomRight (" + lay.bounds[2] + ", " + lay.bounds[3] + "); " + "Width (" + (lay.bounds[2] - lay.bounds[0]) + "); " + "Height (" + (lay.bounds[3] - lay.bounds[1]) + "); " + "Center (" + (lay.bounds[0] + (lay.bounds[2] - lay.bounds[0]) / 2) + ", " + (lay.bounds[1] + (lay.bounds[3] - lay.bounds[1]) / 2) + ");\n\n" ); } function traverseLayers(layerset, layPath, ftn) { for (var i = 0; i < layerset.layers.length; i++) { app.activeDocument.activeLayer = layerset.layers[i]; if (app.activeDocument.activeLayer.typename == "LayerSet") { traverseLayers(app.activeDocument.activeLayer, layPath + app.activeDocument.activeLayer.name + "/", ftn); } else { ftn(app.activeDocument.activeLayer, layPath); } } }; // Main var oldPref = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var logFileName = app.activeDocument.name.replace(/\.[^\.]+$/, ''); var logFile = new File(Folder.desktop + "/" + logFileName + ".txt"); logFile.open("w", "TEXT", "????"); $.os.match(/windows/gi) ? logFile.lineFeed = 'windows' : logFile.lineFeed = 'macintosh'; var doc = app.activeDocument; doc.activeLayer = doc.layers[0] for (var i = 0, count = doc.layers.length; i < count; i++) { app.activeDocument.activeLayer = doc.layers[i] if (doc.layers[i].typename == "LayerSet") { traverseLayers(doc.layers[i], doc.layers[i].name + "/", printData); } else { printData(doc.layers[i], "/"); } } logFile.close(); app.preferences.rulerUnits = oldPref; "EOF";
but it is, as expected, pretty darn slow - for a 400 variously nested layers document it takes several minutes and my old Mac fans spin like crazy.
So I wondered about refactoring it using the "flat-list" (i.e. a list of layers detached from their parent layerSets) ActionManager approach, but how to store full paths (with parent layers)?
I thought about getting the layers via AM, then using a recursive function only to get the layer.parent property, but "parent" is not in the layer's descriptor so I would end up using DOM code again recursively (slow).
Suggestions?
Thank you in advance!
Davide Barranca
---
www.davidebarranca.com
www.cs-extensions.com