¿Script para InDesign que verifica los colores directos de medios tonos?

Gracias a la ayuda de varias personas aquí, casi logré este script para InDesign en el que estoy trabajando. Solo hay otra parte que, aunque no es 100 % necesaria, me encantaría poder ver si ExtendScript puede hacerlo.

Los documentos en los que se ejecutará el script tienen un marco que contiene un archivo EPS vinculado. Este archivo EPS es un archivo vectorial (99% del tiempo) guardado desde Illustrator CS6. (El otro 1 % de las veces, es un mapa de bits al que se le ha asignado un color directo). Necesito poder ver si alguno de los colores en esa ilustración son colores directos que NO son 100 %, en otras palabras, son semitonos.

Probablemente será difícil, ya que no sé si InDesign puede verificar la obra de arte directamente. Es probable que necesite abrir el archivo original en Illustrator, luego verifique no solo los rellenos sólidos y los trazos sólidos, sino también si hay rellenos degradados, trazos degradados u objetos de malla. (Supongo que todos los degradados y mallas contienen, por su propia naturaleza, semitonos). Además, necesitaría identificar (devolver) qué colores directos están semitonos en el arte.

¿Alguien tiene alguna idea sobre cómo se puede lograr esto?

Respuestas (1)

¡BridgeTalk al rescate!

Después de hacer esta pregunta, pasé días investigando y haciendo pruebas y errores para descubrir cómo hacer que esto funcione. Parece que la única forma de ver qué colores en un archivo EPS vinculado en InDesign es abrir ese archivo EPS en Illustrator y verificarlo allí. Afortunadamente, Adobe ha incorporado BridgeTalk en ExtendScript. Por lo tanto, he llegado a las siguientes dos funciones. Primero, la función bridgeToIllustrator, que toma un archivo EPS como entrada y devuelve un Array a la variable global halftoneInks:

/**
 * The BridgeTalk function that will call Illustrator and run its script,
 * returning an array of halftone colors to the variable 'halftoneInks'.
 *
 * @param {File} oFile The EPS file in which to check for halftone colors.
 */
function bridgeToIllustrator(oFile) {
    var resArr = new Array;
    var epsFile = oFile.fullName;
    // create a new BridgeTalk message object
    var bt = new BridgeTalk();
    // send this msg to the Adobe Illustrator CS6 application
    bt.target = "illustrator-16";
    // the script passed to the target application
    bt.body = "var sentFile = File(\"" + epsFile + "\");";
    bt.body += "var SnpSentMessage = {}; SnpSentMessage.create = " + checkForHalftones.toString();
    bt.body += "SnpSentMessage.create(sentFile)";
    bt.onResult = function (resObj) {
        // use eval to reconstruct the array
        resArr = eval(resObj.body);
        // and now we can access the returned array
        halftoneInks = resArr;
    }
    bt.onError = function(errObj)
    {
        $.writeln(errObj.body);
        $.writeln(bt.body);
    }

    // send the message
    bt.send(30);
}

La segunda función es la que se pasará a Illustrator, verificando cada objeto en el archivo EPS y agregando su color de relleno o color de trazo a una Matriz si es un medio tono. Puede haber una mejor manera de escribir esta función, pero por ahora, esto funciona:

/**
 * The main part of the script that will run in Illustrator, checking the file for halftones.
 *
 * @param {File} theFile The file object that will be opened in Illustrator and checked.
 */
function checkForHalftones(theFile) {
    var document = app.open(theFile);

    var colorsArray = [];
    colorsInUse(document.layers[0]);

    function colorsInUse(currPageItem) {
        for (var i = 0; i < currPageItem.pageItems.length; i++) {
            // Stepping through each item on the layer.
            var currentItem = currPageItem.pageItems[i];
            if (currentItem.typename === "GroupItem" && !currentItem.guides) {
                // If it's a group, dig into the group and start the function over.
                colorsInUse(currentItem);
            } else if (currentItem.typename === "RasterItem") {
                if (currentItem.imageColorSpace === ImageColorSpace.CMYK) {
                    $.writeln("Four-color process image in artwork.");
                } else if (currentItem.channels > 1) {
                    if (currentItem.colorants[0] === "Gray") {
                        if (colorsArray.toString().indexOf("Black") === -1) {
                            colorsArray.push("Black");
                        }
                    } else {
                        if (colorsArray.toString().indexOf(currentItem.colorants[0]) === -1) {
                            colorsArray.push(currentItem.colorants[0]);
                        }
                    }
                } else {
                    $.writeln("The raster image in the art file must be a 1-channel bitmap and, thus, does not need to be listed as a halftone.");
                }
            } else if ((currentItem.fillColor || currentItem.strokeColor) && !currentItem.guides) {
                // If the current object has either a fill or a stroke, continue.
                var fillColorType = currentItem.fillColor.typename;
                var strokeColorType = currentItem.strokeColor.typename;
                switch (fillColorType) {
                    case "CMYKColor":
                        if (currentItem.fillColor.cyan === 0 && currentItem.fillColor.magenta === 0 && currentItem.fillColor.yellow === 0) {
                            if (currentItem.fillColor.black === 0) {
                                break;
                            } else if (currentItem.fillColor.black === 100) {
                                break;
                            } else {
                                if (colorsArray.toString().indexOf("Black") === -1) {
                                    colorsArray.push("Black");
                                }
                            }
                        } else {
                            $.writeln("Four color process!");
                        }
                        break;
                    case "GrayColor":
                        if (currentItem.fillColor.gray > 0 && currentItem.fillColor.gray < 100) {
                            if (colorsArray.toString().indexOf("Black") === -1) {
                                colorsArray.push("Black");
                            }
                        }
                        break;
                    case "SpotColor":
                        if (currentItem.fillColor.tint < 100) {
                            if (colorsArray.toString().indexOf(currentItem.fillColor.spot.name) === -1) {
                                colorsArray.push(currentItem.fillColor.spot.name);
                            }
                        }
                        break;
                    case "GradientColor":
                        for (var j = 0; j < currentItem.fillColor.gradient.gradientStops.length; j++) {
                            var gStop = currentItem.fillColor.gradient.gradientStops[j].color;
                            switch (gStop.typename) {
                                case "GrayColor":
                                    if (colorsArray.toString().indexOf("Black") === -1) {
                                        colorsArray.push("Black");
                                    }
                                    break;
                                case "SpotColor":
                                    if (colorsArray.toString().indexOf(gStop.spot.name) === -1) {
                                        colorsArray.push(gStop.spot.name);
                                    }
                                    break;
                                case "CMYKColor":
                                    if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black != 0) {
                                        if (colorsArray.toString().indexOf("Black") === -1) {
                                            colorsArray.push("Black");
                                        }
                                    } else if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black === 0) {
                                        break;
                                    } else {
                                        $.writeln("Four color process.");
                                    }
                                    break;
                                default:
                                    $.writeln("Four color process?");
                            }
                        }
                        break;
                    case "NoColor":
                        break;
                    default:
                        $.writeln("The fill color on object number " + i + " is of type " + fillColorType);
                }

                switch (strokeColorType) {
                    case "CMYKColor":
                        if (currentItem.strokeColor.cyan === 0 && currentItem.strokeColor.magenta === 0 && currentItem.strokeColor.yellow === 0) {
                            if (currentItem.strokeColor.black === 0) {
                                break;
                            } else if (currentItem.strokeColor.black === 100) {
                                break;
                            } else {
                                if (colorsArray.toString().indexOf("Black") === -1) {
                                    colorsArray.push("Black");
                                }
                            }
                        } else {
                            $.writeln("Four color process!");
                        }
                        break;
                    case "GrayColor":
                        if (currentItem.strokeColor.gray > 0 && currentItem.strokeColor.gray < 100) {
                            if (colorsArray.toString().indexOf("Black") === -1) {
                                colorsArray.push("Black");
                            }
                        }
                        break;
                    case "SpotColor":
                        if (currentItem.strokeColor.tint < 100) {
                            if (colorsArray.toString().indexOf(currentItem.strokeColor.spot.name) === -1) {
                                colorsArray.push(currentItem.strokeColor.spot.name);
                            }
                        }
                        break;
                    case "GradientColor":
                        for (var j = 0; j < currentItem.strokeColor.gradient.gradientStops.length; j++) {
                            var gStop = currentItem.strokeColor.gradient.gradientStops[j].color;
                            switch (gStop.typename) {
                                case "GrayColor":
                                    if (colorsArray.toString().indexOf("Black") === -1) {
                                        colorsArray.push("Black");
                                    }
                                    break;
                                case "SpotColor":
                                    if (colorsArray.toString().indexOf(gStop.spot.name) === -1) {
                                        colorsArray.push(gStop.spot.name);
                                    }
                                    break;
                                case "CMYKColor":
                                    if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black != 0) {
                                        if (colorsArray.toString().indexOf("Black") === -1) {
                                            colorsArray.push("Black");
                                        }
                                    } else if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black === 0) {
                                        break;
                                    } else {
                                        $.writeln("Four color process.");
                                    }
                                    break;
                                default:
                                    $.writeln("Four color process?");
                            }
                        }
                        break;

                    case "NoColor":
                        break;
                    default:
                        $.writeln("The stroke color on object number " + i + " is of type " + strokeColorType);
                }
            }
        }
        return;
    }

    document.close(SaveOptions.DONOTSAVECHANGES);

    return colorsArray.toSource();
};

Algunas cosas clave a tener en cuenta sobre este conjunto de funciones:

  1. El punto y coma al final es necesario, ya que toda la función se convertirá en una cadena y se enviará a Illustrator a través de BridgeTalk. Descubrí esto de la manera difícil.
  2. Dado que cualquier información devuelta a InDesign desde Illustrator también se envía como una cadena, una matriz debe manejarse con cuidado. Para enviar una matriz desde Illustrator a InDesign a través de BridgeTalk, deberá enviarse con un .toSource()método. Luego, cuando BridgeTalk ejecuta la .onResultdevolución de llamada, debe usar eval()para reconstruir la matriz en algo utilizable para InDesign. Sí, apesta. Sí, es necesario. Así es como funciona BridgeTalk.
  3. Me costó mucho obtener la sintaxis adecuada para que el archivo se enviara a Illustrator a través de BridgeTalk. Al final, descubrí que siempre que obtenga el archivo .fullNamey luego lo coloque entre comillas dentro del constructor File() dentro del bt.bodyárea, funcionaría. Y, por supuesto, para que las comillas se interpreten como comillas dentro de comillas, cada una debe ir precedida de una barra invertida. ¡Uf! ¡Hablando de confusión!

De todos modos, espero que esto haya sido de ayuda para cualquier otra persona que necesite aprender a usar BridgeTalk entre InDesign e Illustrator. ¡Salud!