Ausgabe
Ich versuche, ein Skript zum Verarbeiten von Ebenen mit Inversion zu erstellen. In Photoshop geschieht dies mit Strg + Klick auf die Ebene. Alle Ebenen in meinem Dokument sind in Gruppen unterteilt. Aus diesem Grund tritt ein Fehler auf (Photoshop versucht, die Gruppe umzukehren). Wie kann ich Gruppen in einer Schleife überspringen oder wie kann ich das beheben?
var doc = app.activeDocument;
var layers =activeDocument.layers;
for (var layerIndex = 0; layerIndex<doc.layers.length; layerIndex++)
{
var layer = layers [layerIndex];
doc.activeLayer = layer;
var idChnl = charIDToTypeID( "Chnl" );
var actionSelect = new ActionReference();
actionSelect.putProperty( idChnl, charIDToTypeID( "fsel" ) );
var actionTransparent = new ActionReference();
actionTransparent.putEnumerated( idChnl, idChnl, charIDToTypeID( "Trsp" ) );
var actionDesc = new ActionDescriptor();
actionDesc.putReference( charIDToTypeID( "null" ), actionSelect );
actionDesc.putReference( charIDToTypeID( "T " ), actionTransparent );
executeAction( charIDToTypeID( "setd" ), actionDesc, DialogModes.NO );
var invert = doc.selection.invert(actionSelect);
var clear = doc.selection.clear(invert);
var des = doc.selection.deselect(clear);
//При попытке выделить группу возникает ошибка, нужно сделать пропуск группы
}
Lösung
In Photoshop sind für Skriptzwecke normale Ebenen vom Typ „ArtLayer“ und Gruppen vom Typ „LayerSet“. Eine Gruppe (LayerSet) kann ein Array sein, das mehrere Ebenen (ArtLayer) oder sogar mehrere Gruppen enthält.
Wie kann ich Gruppen in einer Schleife überspringen?
In Ihrer for -Schleife möchten Sie also wissen, ob die aktuelle Ebene eine tatsächliche Ebene oder eine Gruppe ist, indem Sie ihren Typnamen überprüfen:
...
var layer = layers [layerIndex];
if (layer.typename == "LayerSet") { //if current layer is a group
continue; //skip to next loop element
}
doc.activeLayer = layer;
...
Wenn jedoch alle Ebenen in Ihrem Dokument in Gruppen unterteilt sind, durchläuft Ihre aktuelle for – Schleife nicht die Ebenen innerhalb der Gruppen, da Ihre Ebenenvariable nur die Ebenen der obersten Ebene enthält ( activeDocument.layers ).
Da diese Ebenen der obersten Ebene entweder eine Ebene oder eine Gruppe sein können und der obige Code alle Gruppen überspringt, geht Ihre Schleife nur durch alle Ebenen der obersten Ebene, falls vorhanden, und ignoriert alle Ebenen innerhalb von Gruppen (da Gruppen übersprungen werden).
Mit anderen Worten, wenn Ihr Dokument so strukturiert ist, dass ALLE Ebenen der obersten Ebene Gruppen sind, überspringt Ihre Schleife sie alle und es werden keine Ebenen verarbeitet.
Wie kann ich es reparieren?
Sie können Ihre Schleife reparieren, indem Sie überprüfen, ob die Ebene eine Gruppe ist, und wenn dies der Fall ist, auch die Ebenen der Gruppe durchlaufen. Es gibt viele Möglichkeiten, dies zu tun, je nachdem, wie komplex Sie mit rekursiven Funktionen werden möchten, aber zur Vereinfachung erstellen Sie einfach eine verschachtelte for – Schleife:
...
var layer = layers [layerIndex];
if (layer.typename == "LayerSet") { //if current layer is a group
//if group, loop through its layers
var groupLayers = layer.layers;
for (var i = 0; i < groupLayers.length; i++) {
var layer = groupLayers[i];
doc.activeLayer = layer;
// do your processing here
} //end group layers loop
} //end if LayerSet
...
Da Ihr Verarbeitungscode auch in anderen Fällen angewendet werden kann, z. B. wenn Sie Ebenen der obersten Ebene außerhalb von Gruppen haben, ist es möglicherweise eine gute Idee, ihn in eine eigene Funktion zu extrahieren, anstatt ihn in der for -Schleife zu belassen und dann einfach aufzurufen Funktion innerhalb der Schleife oder wo immer es sonst noch zutreffen mag. So könnte Ihr gesamter Code aussehen:
var doc = app.activeDocument;
var layers = doc.layers;
for (var layerIndex = 0; layerIndex < layers.length; layerIndex++)
{
var layer = layers[layerIndex];
if (layer.typename == "LayerSet") { //if layer is a group
//if group, loop through its layers
var groupLayers = layer.layers;
/** Note that a group could also have nested groups,
which is not accounted for in this scenario **/
for (var i = 0; i < groupLayers.length; i++) {
var layer = groupLayers[i];
doc.activeLayer = layer;
// do your processing here
processLayer();
} //end group layers loop
} //end if LayerSet
} //end doc layers loop
//Function for inverting active layer (or whatever your function does)
function processLayer(){
var idChnl = charIDToTypeID( "Chnl" );
var actionSelect = new ActionReference();
actionSelect.putProperty( idChnl, charIDToTypeID( "fsel" ) );
var actionTransparent = new ActionReference();
actionTransparent.putEnumerated( idChnl, idChnl, charIDToTypeID( "Trsp" ) );
var actionDesc = new ActionDescriptor();
actionDesc.putReference( charIDToTypeID( "null" ), actionSelect );
actionDesc.putReference( charIDToTypeID( "T " ), actionTransparent );
executeAction( charIDToTypeID( "setd" ), actionDesc, DialogModes.NO );
var invert = doc.selection.invert(actionSelect);
var clear = doc.selection.clear(invert);
var des = doc.selection.deselect(clear);
return;
} //end processLayer()
FYI: Es ist eine gute Idee, eine Kopie der Photoshop-Javascript-Referenz zu haben , wenn Sie Photoshop-Skripts entwickeln. Sie können das Referenz-PDF verwenden, um alle Eigenschaften und Methoden anzuzeigen, die für ArtLayer-Ebenen und LayerSets-Ebenen (Gruppen) verfügbar sind, wie Name, Deckkraft, ob sie sichtbar ist usw.
Beantwortet von – Andrei I. Gere
Antwort geprüft von – Marilyn (FixError Volunteer)