Благодаря помощи разных людей, я почти прибил этот скрипт для InDesign, над которым я работаю. Есть только один момент, который, хотя и не является на 100% необходимым, я хотел бы увидеть, может ли ExtendScript это сделать.
Документы, над которыми будет работать скрипт, имеют фрейм, который содержит связанный EPS-файл. Этот файл EPS представляет собой векторный файл (в 99% случаев), сохраненный в Illustrator CS6. (В другом 1% случаев это растровое изображение, которому был назначен плашечный цвет.) Мне нужно иметь возможность видеть, являются ли какие-либо цвета в этом изображении плашечными цветами, которые НЕ являются 100% — другими словами, они являются полутонами.
Это, вероятно, будет сложно, так как я не знаю, может ли InDesign напрямую проверить иллюстрацию. Скорее всего, потребуется открыть исходный файл в Illustrator, а затем проверить не только сплошные заливки и сплошные штрихи, но и наличие градиентных заливок, градиентных штрихов или объектов сетки. (Я исхожу из того, что все градиенты и сетки по своей природе содержат полутона.) Кроме того, необходимо будет определить (возвратить), какие плашечные цвета являются полутонами в искусстве.
У кого-нибудь есть идеи о том, как это можно реализовать?
BridgeTalk на помощь!
После того, как я задал этот вопрос, я провел дни, проводя исследования и пробы и ошибки, чтобы выяснить, как заставить это работать. Кажется, что единственный способ увидеть, какие цвета в связанном файле EPS в InDesign, — это открыть этот файл EPS в Illustrator и проверить его там. К счастью, Adobe включила BridgeTalk в ExtendScript. Таким образом, я придумал следующие две функции. Во-первых, функция bridgeToIllustrator, которая принимает на вход EPS-файл и возвращает в глобальную переменную Array 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);
}
Вторая функция — это та, которая будет передана в Illustrator, проверяя каждый объект в файле EPS и добавляя его цвет заливки или цвет обводки в массив, если это полутон. Возможно, есть лучший способ написать эту функцию, но на данный момент это работает:
/**
* 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();
};
Несколько ключевых моментов, которые следует отметить в отношении этого набора функций:
.toSource()
метода. Затем, когда BridgeTalk выполняет .onResult
обратный вызов, вам нужно использовать eval()
для того, чтобы он реконструировал массив во что-то, пригодное для использования в InDesign. Да, это отстой. Да, это необходимо. Именно так работает BridgeTalk..fullName
, а затем помещаю его в кавычки внутри конструктора File() внутри bt.body
области, он будет работать. И, конечно же, чтобы кавычки интерпретировались как кавычки внутри кавычек, перед каждой из них должна стоять обратная косая черта. Вау! Разговор о путанице!В любом случае, я надеюсь, что это помогло всем, кому нужно научиться использовать BridgeTalk между InDesign и Illustrator. Ваше здоровье!