¿Cuál es la forma correcta de contar todas las capas que se van a convertir en un script?

Estoy usando un script ( de Sergey Kritskiy de esta pregunta ) para seleccionar todas las formas con un color específico y reemplazar este color con otro. Hice algunos cambios, también agregué una confirmventana ( en el paso 5 ) que da una especie de mensaje de "informe" antes de comenzar a hacer sus cosas. En el mensaje de la ventana de confirmación, también tengo esto layers.lengthpara informarme cuántas capas se cambiarán. Pero cada vez me da el mismo número!!! Por ejemplo, si tengo 300 capas, 150 azules y 150 rojas, incluso si elijo cambiar solo las azules, ¡ layers.lengthtodavía dice 300! Aquí está el guión como se ve ahora...

Les recuerdo que soy nuevo en photoshop scripting y no soy un as de Java...

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();

EDITAR: si prueba el script, en el segundo paso, donde solicita el nombre de la capa, ¡simplemente déjelo vacío!

Respuestas (1)

En primer lugar, SetLayerName()no devuelve nada y layerNameno está definido. Debería ser así:

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

Luego getLayersData()devuelve las capas que coinciden con un tipo y nombre específicos, NO con un color específico. Si desea mostrar cuántas capas se cambiarán, también debe agregar esta condición antes de enviar una capa a lyrs:if (curColor.rgb.hexValue == colorToChange.rgb.hexValue) lyrs.push(lyr);

Sería mucho más fácil para usted si pasara una hora en cualquier curso de JavaScript en cualquier plataforma de enseñanza de código.

actualizar:

En las líneas 42 y 43 está definiendo sourceColory targetColorsaliendo de matrices ( color1_rgby color2_rgb) y luego en la línea 54 está definiendo colorToChangedesde sourceColor. Básicamente estás haciendo

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;

Tanto your sourceColorcomo colorToChangese pueden definir antes getLayersData() porque usan valores de color1_rgb, que se define al principio. Aún más, estás usando 3 variables diferentes para definir lo mismo. No necesita ambos color1_rgby sourceColor, solo necesita obtener el color una vez y luego usarlo para todo.

    var colorToChange = app.foregroundColor;
    var layers = getLayersData();
¿ Dónde exactamente debo colocar esta Ifcondición? Lo pongo justo antes lyrs.push(lyr);y me sale undefined is not an object!!! ¡Creo que debería seguir tu consejo con este curso de JavaScript seguro! :(
Eso se debe a que está creando colorToChangedespués de llamar getLayersData(), por lo que colorToChangeno existe cuando se verifica la condición. Ponga su conjunto var colorToChange = new SolidColor();y establezca sus valores antes de llamar algetLayersData()
¡No puedo crear colorToChangeantes getLayersData()porque colorToChange"obtiene" de getLayersData()entonces tiene que ser primero!
No, tu colorToChangeno obtienes nada degetLayersData()
¡No puedo encontrar la manera de "encajar" esto if (curColor.rgb.hexValue == colorToChange.rgb.hexValue)! :( Ya comencé un curso de javascript que dijiste, así que para entender mejor algunas cosas, pero por ahora, ¿puedes dar un ejemplo práctico para esto?
he actualizado mi respuesta