Was ist der richtige Weg, um alle Ebenen zu zählen, die sich in ein Skript ändern werden?

Ich verwende ein Skript ( von Sergey Kritskiy aus dieser Frage ), um alle Formen mit einer bestimmten Farbe auszuwählen und diese Farbe durch eine andere zu ersetzen . Ich habe einige Änderungen vorgenommen, ich habe auch ein confirmFenster hinzugefügt ( bei Schritt 5 ), das eine Art "Bericht"-Nachricht ausgibt, bevor es losgeht. In der Meldung des Bestätigungsfensters habe ich auch dies, layers.lengthum mir mitzuteilen, wie viele Ebenen geändert werden. Aber jedes Mal gibt mir die gleiche Nummer!!! Wenn ich zum Beispiel 300 Ebenen habe, 150 blaue und 150 rote, selbst wenn ich mich entscheide, nur blaue zu ändern, layers.lengthsagt das immer noch 300 !!! Hier ist das Skript, wie es jetzt aussieht ...

Ich erinnere Sie daran, dass ich neu im Photoshop-Scripting bin und kein Java-Ass bin ...

function main(){

    var hexToRGB = function(hex) { var r = hex >> 16; var g = hex >> 8 & 0xFF; var b = hex & 0xFF; return [r, g, b]; };

    function SetLayerType() {
        var layerType='';
        while(layerType == null || layerType == ''){
            layerType = prompt('Enter layers type...', '', 'Step 1');
        }                   
        return layerType;
    }
    layerType = SetLayerType();

    function SetLayerName() {
        var layerName = prompt('Enter layers name...', '', 'Step 2');
    }
    layerName = SetLayerName();

    if (confirm('Click "Yes" and choose the color you want to replace...', false, 'Step 3')) {
        if (app.showColorPicker()){
            var color1_decimal = app.foregroundColor.rgb.hexValue;
            var color1_hexadecimal = color1_decimal.toString(16);
            var color1_rgb = hexToRGB(parseInt(color1_hexadecimal, 16));
        };
    }
    else {
        return;
    };

    if (confirm('Click "Yes" and choose the new color...', false, 'Step 4')) {
        if (app.showColorPicker()){
            var color2_decimal = app.foregroundColor.rgb.hexValue;
            var color2_hexadecimal = color2_decimal.toString(16);
            var color2_rgb = hexToRGB(parseInt(color2_hexadecimal, 16));
        };
    }
    else {
        return;
    };

    var layers = getLayersData(),
        sourceColor = [color1_rgb[0], color1_rgb[1], color1_rgb[2]], 
        targetColor = [color2_rgb[0], color2_rgb[1], color2_rgb[2]];
    if (confirm ('You are about to replace color for [' + layers.length + '] shapes in\n[' + activeDocument.name + '] document.\n\nOld color: (' + sourceColor + ')\nNew Color: (' + targetColor + ')\n\nDo you want to continue?',  false, 'Step 5')) {
        var colorToChange = new SolidColor();
        colorToChange.rgb.red = sourceColor[0];
        colorToChange.rgb.green = sourceColor[1];
        colorToChange.rgb.blue = sourceColor[2];
        for (var i = 0; i < layers.length; i++) {
            if (layers[i].color.rgb.hexValue == colorToChange.rgb.hexValue) {
                selectById(layers[i].id);
                changeShapeColor(targetColor);
            }
        }
    }
    else {
        return;
    };

    function getLayersData() {
        var lyrs = [];
        try {
            activeDocument.backgroundLayer;
            var layers = 0
        } 
        catch (e) {
            var layers = 1;
        };
        while (true) {
            ref = new ActionReference();
            ref.putIndex(charIDToTypeID('Lyr '), layers);
            try {
                var desc = executeActionGet(ref);
            } 
            catch (err) {
                break;
            }
            var lyr = {};
            lyr.type = desc.getInteger(stringIDToTypeID("layerKind"));
            lyr.name = desc.getString(charIDToTypeID("Nm  "));
            lyr.id = desc.getInteger(stringIDToTypeID("layerID"));
            if (lyr.type == layerType && lyr.name.match(layerName)) {
                var adj = desc.getList(stringIDToTypeID("adjustment")).getObjectValue(0);
                if (adj.hasKey(stringIDToTypeID("color"))) {
                    var curColor = new SolidColor();
                    curColor.rgb.red = adj.getObjectValue(stringIDToTypeID("color")).getUnitDoubleValue(stringIDToTypeID("red"));
                    curColor.rgb.green = adj.getObjectValue(stringIDToTypeID("color")).getUnitDoubleValue(stringIDToTypeID("grain"));
                    curColor.rgb.blue = adj.getObjectValue(stringIDToTypeID("color")).getUnitDoubleValue(stringIDToTypeID("blue"));
                    lyr.color = curColor;
                    lyrs.push(lyr);
                }
            }
            layers++;            
        }
        return lyrs
    };

    function changeShapeColor(color) {
        var desc8 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putEnumerated(stringIDToTypeID('contentLayer'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
        desc8.putReference(charIDToTypeID('null'), ref1);
        var desc9 = new ActionDescriptor();
        var desc10 = new ActionDescriptor();
        desc10.putDouble(charIDToTypeID('Rd  '), color[0]);
        desc10.putDouble(charIDToTypeID('Grn '), color[1]);
        desc10.putDouble(charIDToTypeID('Bl  '), color[2]);
        desc9.putObject(charIDToTypeID('Clr '), charIDToTypeID('RGBC'), desc10);
        desc8.putObject(charIDToTypeID('T   '), stringIDToTypeID('solidColorLayer'), desc9);
        executeAction(charIDToTypeID('setd'), desc8, DialogModes.NO);
    };

    function selectById(id) {
        var desc1 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putIdentifier(charIDToTypeID('Lyr '), id);
        desc1.putReference(charIDToTypeID('null'), ref1);
        executeAction(charIDToTypeID('slct'), desc1, DialogModes.NO);
    };

}
main();

BEARBEITEN: Wenn Sie das Skript im zweiten Schritt ausprobieren, wo Sie nach dem Ebenennamen gefragt werden, lassen Sie es einfach leer !!!

Antworten (1)

Zunächst einmal SetLayerName()gibt your nichts zurück und your layerNameist undefiniert. Es sollte so sein:

function SetLayerName() {
    return prompt('Enter layers name...', '', 'Step 2');
}
var layerName = SetLayerName();

Gibt dann getLayersData()Ebenen zurück, die einem bestimmten Typ und Namen entsprechen, NICHT einer bestimmten Farbe. Wenn Sie anzeigen möchten, wie viele Ebenen geändert werden, sollten Sie auch diese Bedingung hinzufügen, bevor Sie eine Ebene an verschieben lyrs:if (curColor.rgb.hexValue == colorToChange.rgb.hexValue) lyrs.push(lyr);

Es wäre viel einfacher für Sie, wenn Sie eine Stunde mit einem beliebigen JavaScript-Kurs auf einer beliebigen Code-Lehrplattform verbringen würden.

aktualisieren:

In Zeile 42 und 43 definieren Sie sourceColorund targetColorvon verlassenden Arrays ( color1_rgbund color2_rgb) und dann in Zeile 54 definieren Sie colorToChangevon sourceColor. Im Grunde tun Sie

var color1_rgb = app.foregroundColor.rgb.values; // stripping down the SolidColor object
var layers = getLayersData(); //colorToChange is needed here
var sourceColor = color1_rgb;
var colorToChange = new SolidColor() // uses values of sourceColor;

Sowohl Ihr sourceColorals auch colorToChangekönnen zuvor getLayersData() definiert werden , da sie Werte von verwenden color1_rgb, die am Anfang definiert werden. Darüber hinaus verwenden Sie 3 verschiedene Variablen, um dasselbe zu definieren. Du brauchst nicht beides color1_rgbund sourceColor, du musst dir die Farbe nur einmal besorgen und sie dann für alles verwenden.

    var colorToChange = app.foregroundColor;
    var layers = getLayersData();
Wo genau soll ich diese IfBedingung platzieren? Ich stelle es richtig vor lyrs.push(lyr);und ich bekomme undefined is not an object!!! Ich denke, ich sollte Ihrem Rat mit diesem JavaScript-Kurs auf jeden Fall folgen!!! :(
Das liegt daran, dass Sie erstellen, colorToChangenachdem Sie aufgerufen haben getLayersData(), also colorToChangenicht existiert, wenn die Bedingung überprüft wird. Setzen Sie Ihr ganzes var colorToChange = new SolidColor();und setzen Sie seine Werte vor dem Aufrufen dergetLayersData()
Ich kann nicht colorToChangevorher erstellen getLayersData(), weil colorToChange"bekommt" von getLayersData()also muss es zuerst sein !!!
Nein, du colorToChangebekommst nichts vongetLayersData()
Ich kann den Weg nicht finden, das zu "passen" if (curColor.rgb.hexValue == colorToChange.rgb.hexValue)!!! :( Ich habe bereits einen Javascript-Kurs gestartet, wie Sie gesagt haben, um einige Dinge besser zu verstehen, aber können Sie für den Moment bitte ein funktionierendes Beispiel dafür geben?
Ich habe meine Antwort aktualisiert