Скрипт для InDesign, который проверяет полутоновые плашечные цвета?

Благодаря помощи разных людей, я почти прибил этот скрипт для InDesign, над которым я работаю. Есть только один момент, который, хотя и не является на 100% необходимым, я хотел бы увидеть, может ли ExtendScript это сделать.

Документы, над которыми будет работать скрипт, имеют фрейм, который содержит связанный EPS-файл. Этот файл EPS представляет собой векторный файл (в 99% случаев), сохраненный в Illustrator CS6. (В другом 1% случаев это растровое изображение, которому был назначен плашечный цвет.) Мне нужно иметь возможность видеть, являются ли какие-либо цвета в этом изображении плашечными цветами, которые НЕ являются 100% — другими словами, они являются полутонами.

Это, вероятно, будет сложно, так как я не знаю, может ли InDesign напрямую проверить иллюстрацию. Скорее всего, потребуется открыть исходный файл в Illustrator, а затем проверить не только сплошные заливки и сплошные штрихи, но и наличие градиентных заливок, градиентных штрихов или объектов сетки. (Я исхожу из того, что все градиенты и сетки по своей природе содержат полутона.) Кроме того, необходимо будет определить (возвратить), какие плашечные цвета являются полутонами в искусстве.

У кого-нибудь есть идеи о том, как это можно реализовать?

Ответы (1)

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

Несколько ключевых моментов, которые следует отметить в отношении этого набора функций:

  1. Точка с запятой в конце необходима, так как вся функция будет преобразована в строку и отправлена ​​в Illustrator посредством BridgeTalk. Я обнаружил это трудным путем.
  2. Поскольку любая информация, возвращаемая в InDesign из Illustrator, также отправляется в виде строки, с массивом необходимо обращаться осторожно. Чтобы отправить массив из Illustrator обратно в InDesign через BridgeTalk, его необходимо отправить с помощью .toSource()метода. Затем, когда BridgeTalk выполняет .onResultобратный вызов, вам нужно использовать eval()для того, чтобы он реконструировал массив во что-то, пригодное для использования в InDesign. Да, это отстой. Да, это необходимо. Именно так работает BridgeTalk.
  3. У меня было время получить правильный синтаксис для отправки файла в Illustrator через BridgeTalk. В конце концов, я обнаружил, что пока я получаю файл .fullName, а затем помещаю его в кавычки внутри конструктора File() внутри bt.bodyобласти, он будет работать. И, конечно же, чтобы кавычки интерпретировались как кавычки внутри кавычек, перед каждой из них должна стоять обратная косая черта. Вау! Разговор о путанице!

В любом случае, я надеюсь, что это помогло всем, кому нужно научиться использовать BridgeTalk между InDesign и Illustrator. Ваше здоровье!