101 СПОСОБ  ЗАРАБОТАТЬ   НА ПЕЧАТИ

Универсальная ищейка изображений

  • Михаил Борисов
  • 8 апреля 2008 г.
  • 4274

Нередкий случай при вёрстке публикаций со значительным количеством иллюстраций — проблема с изображениями. Некоторые в результате трансформаций оказываются настолько увеличены в размере по сравнению с оригиналами, что при печати без коррекции окажутся плохого качества. Особенно остро вопрос стоит, когда отдельные фото поступают на вёрстку в последний момент, когда уже нет времени на проверку их разрешения. Решить проблему иллюстраций с низким конечным разрешением (термин «эффективное» точнее отображает суть дела) можно несколькими способами.

Первый — использовать средства допечатной проверки (preflight). Классический вариант — встроенные функции Adobe Acrobat, альтернатива — Flight Check и пр. В процессе проверки ПО отображает в виде списка объекты, имеющие параметры, отличающиеся от заданных. Вроде бы удобно, да не совсем. Давайте подсчитаем временные затраты на исправление ситуации на примере популярного Acrobat.

Pro et contra

Сначала надо сформировать PDF: это четверть часа и больше, в зависимости от количества и качества изображений в публикации. Сам preflight-анализ тоже не происходит мгновенно. Третий шаг — получение информации о проблемных изображениях для принятия корректирующих мер. Приходится возвращаться в публикацию, переходить на обозначенную страницу, на ней переходить на проблемное изображение, и лишь только тогда начинаются корректирующие действия. Потом надо снова возвращаться в preflight-пакет, смотреть, на какой странице следующее проблемное изображение, и т. д. Последовательность обязательна для каждого потенциально опасного изображения; какой уж тут «эффективный рабочий процесс»…

Второй способ — использовать скриптинг. Получить результирующее разрешение просто, даже не нужно определять масштаб изображения: в InDesign все значения доступны верстальщику в явном виде. Другой вопрос: как достичь эффективного взаимодействия с пользователем, чтобы ему было максимально удобно переходить к найденным изображениям (следующее действие в InDesign — запуск операции Edit in…)? В результате нескольких проб выкристаллизовался такой вариант: результаты поиска отображаются в виде списка с названиями проблемных файлов, в котором для оценки степени проблематичности также указаны их эффективные разрешения. Поскольку на одной странице может быть до десятка изображений, при выборе конкретного из списка предусмотрен автоматический переход на выбранное, с его выделением (реализовать следующую за этим операцию Edit in Photoshop можно через механизм, заложенный в Bridge).

В таком случае поиск изображений с разрешением ниже заданного сводится к запуску скрипта, результатом чего будет переход только к одному выбранному изображению. Последующий запуск приведёт к переходу на следующее изображение и т. д. Скрипт запускается через очень удобную панель Scripts либо через клавиатурный ускоритель — каждый выбирает оптимальный вариант. Производительность высока.

Кроме экономии времени на поиск проблемных файлов данным скриптом, следует помнить о побочном, но полезном эффекте от использования вообще любого самостоятельно написанного скрипта — общее повышение настроения: это один из тех случаев, когда не мы, а «мир прогнулся под нас». Заметьте: вы не просто работаете в программе, а управляете ею — и это две большие разницы!

Переходим к практике

Создаём переменные для работы скрипта.

  1. imageList — для занесения порядкового номера изображения (он уникален для каждого объекта публикации, поэтому впоследствии через него можно будет найти изображение).
  2. imagePageList — для хранения номера страницы с проблемным изображением (для перехода на неё, чтобы можно было вызвать операцию Edit in Photoshop).
  3. imageInfoList — для записи сопутствующей информации об изображении (эффективное разрешение по горизонтали/вертикали, название файла, расположение на диске — всё будет отображаться в списке; при необходимости лишние данные исключим).

document = app.activeDocument;
imageList = new Array ();
imagePageList = new Array ();
imageInfoList = new Array ();
numImagesFound = 0;

Запуск скрипта приводит к появлению диалогового окна, в котором предлагается задать минимальное разрешение, после чего скрипт начинает по очереди анализировать каждое присутствующее в публикации растровое изображение. Входящие в состав векторных скриптом не анализируются, поскольку это выходит за рамки возможностей InDesign — в таком случае понадобится использовать связку с Adobe Bridge, дабы задействовать механизм Illustrator, но это тема отдельного скрипта и статьи.

 

myDlg = app.dialogs.add ({name:”Поиск изображений с разрешением ниже заданного”});
column = myDlg.dialogColumns.add ();
row = column.dialogRows.add ();
row.staticTexts.add ({staticLabel:”Найти все изображения с разрешением (ppi) ниже”});

   row = column.dialogRows.add ();
   editbox = row.integerEditboxes.add ({editContents:”300”, minimumValue:72, maximumValue:600});

dialogCanceled = (myDlg.show() == false); 
dpiValue = editbox.editContents;

myDlg.destroy ();
if (dialogCanceled) {
   exit ();
}

Созданное нами окно 

Значение по умолчанию для разрешения editContents выбрано равным 300 ppi, что можно считать стандартом. Параметры minimumValue и maximumValue ограничивают диапазон поиска по разрешению разумными пределами: при их превышении InDesign выдаст предупреждение и введённое значение проигнорирует.

Поиск проблемных изображений…

Просматриваем каждую страницу и среди всех расположенных на ней элементов находим растровые объекты, каждый
инспектируем отдельно. Небольшое отступление: если на странице растровых объектов нет, InDesign считает, что их количество не 0, а ‘undefined’, чем сбивает плавное течение скрипта (очевидный прокол разработчиков; впрочем, в скриптинге InDesign их гораздо меньше, чем в досточтимом QuarkXPress, несмотря на гораздо более полную функциональность, к тому же не ограниченную исключительно AppleScript). Поэтому делаем дополнительную проверку, чтобы обезопасить себя от подобных «сюрпризов»:

 

for (i=0; i < document.pages.length; i++)
{
currPage = document.pages[i];

for (j=0; j < currPage.allPageItems.length; j++)
{
currPageItem = currPage.allPageItems[j];

   if (typeof currPageItem.images != ‘undefined’)
   {
   for (k=0; k < currPageItem.images.length; k++)
   {
   currImage = currPageItem.images[k];

Если эффективное разрешение effectivePpi (которое получается в результате применения всех трансформаций над изображением) по горизонтали либо вертикали (хранится в массиве из двух чисел: первое effectivePpi[0] — разрешение по горизонтали, второе effectivePpi[1] — по вертикали) меньше заданного, для удобства обработки заносим информацию о таком изображении в три ранее созданных массива imageList, imagePageList, imageInfoList:


    if (currImage.effectivePpi[0] < dpiValue || currImage.effectivePpi[1] < dpiValue)
    {
    imageList[numImagesFound] = currImage;
    imagePageList[numImagesFound] = currPage;

    imageInfoList[numImagesFound] = “Стр. “ + currPage.name +
    “ эффективное PPI= “ + currImage.effectivePpi[0] + “х” + currImage.effectivePpi[1] +
    “, расположение: ‘” + currImage.itemLink.filePath + “’”;
    numImagesFound ++;
    }
   }
  }
 }
}

Если публикация в данном вопросе безукоризненна, поздравляем верстальщика:

if (numImagesFound == 0)
{
alert (“Изображений с разрешением ниже “ + dpiValue + “ DPI не найдено.”, “Поиск изображений по их разрешению”);
exit ();
}

…и их отображение

Если же в публикации не всё гладко, отображаем другой диалог, в котором и выводим список всех проблемных изображений. Диалог — таблица из двух строк: в одной — подсказка для пользователя (staticTexts), что он должен сделать, в другой — собственно сформированный нами список (dropdown), в котором первый элемент уже выделен (selectedIndex:0).

dlg = app.dialogs.add ({name:”Поиск изображений по их разрешению”, canCancel:true});
column = dlg.dialogColumns.add ();
row = column.dialogRows.add ();
row.staticTexts.add ({staticLabel:”Выберите изображение и нажмите OK для перехода на него”});
row = column.dialogRows.add ();
dropdown = row.dropdowns.add ({minWidth:400, stringList:imageInfoList, selectedIndex:0});

Сразу после щелчка по кнопке OK скрипт переходит на страницу, содержащую проблемное изображение (её порядковый номер содержится в ранее созданном нами массиве imagePageList). Кроме того, выбранное изображение обозначается выделением (его порядковый номер хранится в массиве imageList).

if (dlg.show() == true)
{
   document.layoutWindows[0].activePage = imagePageList[dropdown.selectedIndex];

   document.select (imageList[dropdown.selectedIndex]);
}
dlg.destroy ();

Вот и всё. Кстати, на базе этого скрипта был написан другой, «отлавливающий» переполнение текста. Он отличается только логикой поиска текстовых фреймов, всё остальное — абсолютно идентично. Удачного скриптования и побольше творческой работы!


Принцип работы с окнами диалога

  1. Создание контейнера для диалога.
  2. Заполнение его необходимыми элементами.
  3. Вывод на экран (show()).
  4. Считывание установленных в нём значений для использования в скрипте.
  5. Удаление диалога из памяти и освобождение затрачиваемых на его отображение ресурсов (destroy()) .

Объектная модель пользовательских диалогов

С точки зрения объектной модели, это типичные объекты InDesign (dialogs), имеющие свои характеристики (свойства) и возможности (методы). Для создания нового окна служит метод add(), универсальный для добавления любых объектов. Круглые скобки в названии любого метода обязательны: это отличительный признак метода от свойства; в них часто уточняется способ действия (передаются параметры). Если уточняющих параметров нет, скобки остаются пустыми.

JavaScript позволяет в момент создания нового объекта задать «на лету» его свойства, которые заключаются в круглые скобки, при этом знак присвоения (=) меняется на двоеточие.

myObjects.add({firstProperty: firstPropertyValue, secondProperty: secondPropertyValue …})

Содержимое окна рассматривается как одна большая таблица из строк (создаются методом dialogColumns.add()), состоящих из столбцов (метод dialogRows.add()). Каждую образующуюся таким образом ячейку можно рассматривать как новую таблицу, что позволяет создавать диалоговые окна неограниченной сложности.

В громоздких окнах связанные элементы можно объединять в отдельные группы (borderPanels.add()), которые отображаются как рельефные области.

Каждый элемент управления в окне диалога — отдельный объект. Все они делятся на следующие типы:

Объекты окна диалога имеют специфические методы и свойства. Например, checkbox имеет свойство, в котором хранится текст названия элемента управления (staticLabel) и состояние флажка (checkedState); содержимое всплывающего списка имеет свойство selectedIndex, которое показывает, какой элемент списка будет по умолчанию активным (занимающиеся дизайном веб-страниц найдут много общего с html-формами).

Соответствие элементов окна диалога


Стандартный метод построения диалогов

Диалоги в InDesign строятся, как и таблицы в HTML-документах. Сначала задаётся контейнер (dialog), потом добавлением необходимого количества строк (dialogRows, аналог <TR>) и столбцов (dialogColumns, аналог <TD>) конструируется каркас таблицы, ячейки которой затем заполняются элементами управления. При необходимости полученные ячейки могут делиться, что позволяет создавать диалоги любой степени сложности. Однако код разрастается ещё быстрее, поэтому иногда прибегают к упрощённому, более управляемому варианту (см. врезку ниже).


Упрощённый вариант создания диалогов

Отличие от традиционного подхода — не задаём для каждой новой строки конструкции типа row = column.dialogRows.add(). Достаточно задать только столбцы, где и перечислять требуемые элементы. Вот как строится достаточно сложное окно.

myDialog = app.dialogs.add();

//крайняя левая колонка — только для текста, следующая — для соответствующих значений и т. д.

myLabelsColumn1 = myDialog.dialogColumns.add();
myLabelsColumn1.staticTexts.add({staticLabel:”Repeat Count:”});

//пробельный элемент — исключительно ради отделения одной группы параметров от другой

myLabelsColumn1.staticTexts.add();
myLabelsColumn1.staticTexts.add({staticLabel:”Horizontal Offset:”});
myLabelsColumn1.staticTexts.add({staticLabel:”Vertical Offset:”});

//снова пробельный элемент

myLabelsColumn1.staticTexts.add();
myLabelsColumn1.staticTexts.add({staticLabel:”Rotation:”});
myLabelsColumn1.staticTexts.add({staticLabel:”Skew:”});
и т. д.

//вторая колонка — для значений параметров из первой колонки

myControlsColumn1 = myDialog.dialogColumns.add();
myRepeatField = myControlsColumn1.integerEditboxes.add({editValue:2});
и т. д.

ПОХОЖИЕ СТАТЬИ


Новый номер

Тема номера: С иголочки: всё о брендировании текстиля. RICOH Pro C7500. Скоростной УФ-принтер Artis CX-360G Gen 51. Текстильлегпром 2024. Кто побеждает в борьбе: DTG или DTF? День рождение будущего. Agfa Anapurna Ciervo H3200 + Спецпроект Publish Junior



Какой следующий принтер вы купите себе на производство?
    Проголосовало: 38