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?
¡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:
.toSource()
método. Luego, cuando BridgeTalk ejecuta la .onResult
devolució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..fullName
y 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!