На главную страницу
Автоматизация работы с помощью скриптов в Photoshop 7
Александр Поляков


Лень, как известно, является двигателем прогресса. Человек я ленивый, а стало быть, прогрессивный, посему и испытываю непреодолимую тягу к компьютерам, автоматизации и прочим фишечкам и шашечкам, которые дают возможность, сомкнув на пузе персты, наблюдать, как мой продвинутый калькулятор усердно пашет, отрабатывая очередную "вкусную", высокотехнологичную, но дорогую железку.

Мой постоянный клиент — директор диспетчерской конторы (такси). В его умную голову пришла мысль о том, что у всех его абонентов должны быть абонентские карточки. Эскиз утвержден. Абонентов было много, карточек тоже, мысль о гонораре начала заранее согревать душу. Остудило меня то, что карточки должны были быть пронумерованы: проставив номера на первых сорока талончиках, я остыл окончательно и призвал свою музу — лень.

В принципе, можно заставить "Фотошоп" отрисовать кучу одинаковых картинок и проставить на них номера стандартными средствами (хотя многие это отрицают), но способ это не элегантный, жутко медленный, да и качество результата может обмануть только клиента (хотя… что еще нужно:)? Между тем, почти во все свои продукты ("Иллюстратор", "Акробат", "Премьер" и т.д.) народная фирма Adobe включила исключительно полезную функцию — скрипты. "Фотошоп", как ни странно, этой радостью оказался обделен, но, если скачать с ftp.adobe.com архив PhotoshopScripting102a.exe, то о многих рутинных, но не поддающихся автоматизации с помощью Actions вещах можно будет забыть. После установки не забудьте скопировать в каталог с плагинами файл ScriptListener.8li (он находится в директории Utilities дистрибутива и существенно поможет нам позже в создании скриптов).

Итак, карточки. Определимся с размерами: как правило, выбирают размер визитной карточки (9х5 см) или карманного календарика (7х10 см). Предположим, размеры карточки — 7х10 см. Рисуем картинку, которая будет фоном — совершенно безразлично для последующих стадий. Я взял фотографии навороченного "Мерса" и добавил таксистские шашечки, название диспетчерской конторы и номера телефонов. Выбрав инструмент обрезки Crop [C], выставляем в опциях:

Width=10 cm
Height=7 cm
Resolution=300 dpi

Теперь обрезаем картинку до нужных размеров и на всякий пожарный случай сохраняем заготовку на диск.

Пришла пора воспользоваться скриптами. Задачей сегодня, напоминаю, является производство большого количества нумерованных карточек, на которых нам очень-очень лень ручками прописывать номера. После установки упомянутого выше плагина в меню File/Automate появится новая опция Scripts, которая позволяет запустить несколько имеющихся после установки скриптов либо указать путь к собственным.

Если вы последовали моему совету и переписали в папку с плагинами файл ScriptListe-ner.8li, то теперь стоит заглянуть в корневую директорию диска, на котором у вас установлен "Фотошоп", — после рисования в редакторе подложки для карточки (теперь, впрочем, как и после любого другого действия в "Фотошопе") там появились файлы ScriptingListenerJS.log и ScriptingListenerVB.log — это запись почти всех ваших действий на языках JavaScript и Visual Basic соответственно. В архиве с плагином вы найдете подробную документацию по управлению "Фотошопом" с помощью скриптов. Кое-что меня, правда, огорчило: в справочном руководстве расписаны методы и свойства, присущие объектам "Фотошопа" — слоям, путям, выделениям, маскам и т.д., а в логах действия записываются в виде исполнения господь знает каких действий с непонятно что обозначающими идентификаторами. Тем не менее, это может быть очень полезно, когда вы хотите вызвать из скрипта функцию, не имеющую на данный момент соответствующего ей метода у объектов "Фотошопа", — например, новый фильтр.

Обнаружив эти файлы, поступаем жестоко — удаляем их. Затем снова переключаемся в "Фотошоп" и инструментом Text [T] прописываем на карточке номер "00001", присваиваем надписи эффекты (я добавил только Drop Shadow), если необходимо, и снова смотрим лог (предположим, что нам больше нравится Java Script). Хм-м-м... Разбираться в содержимом 20-килобайтного файла ну никак не хочется. И не нужно. Копируем его во временную папку и переименовываем в insert_number.js, открываем его в любом редакторе — например, в notepad. В самом начале вставляем заголовок функции:

function insert_number (number) {
а в конце файла — правую фигурную скобку: "}". Теперь в первых строчках нашей функции вставляем:
tmp=''+number;

Здесь перед знаком "+" стоят две одинарные кавычки. Так мы показываем интерпретатору, что переменная tmp имеет строковый тип. Пишем дальше:

if (number<10000) then tmp='0'+tmp;
if (number<1000) then tmp='0'+tmp;
if (number<100) then tmp='0'+tmp;
if (number<10) then tmp='0'+tmp;

Этими строчками мы добавим нули в начале номера, если он получается коротким — меньше пяти цифр. Дальше ищем в тексте функции введенную нами в "Фотошопе" надпись "00001" и меняем ее на "tmp" (без кавычек). Теперь, если запустить на выполнение скрипт (File/Automate/Scripts/ Browse…), то мы, увы, ничего не увидим. Ничего странного: мы создали функцию, но не вызвали ее. Если вписать в начало скрипта строчку

insert_number(999);

и запустить на выполнение, то мы увидим, как "Фотошоп" создает новый слой с заданным нами текстом "00999". Теперь удалите из скрипта этот тестовый вызов — он нам больше не нужен.

Теперь давайте решим, как мы будем рисовать все те карточки, которые следуют за первой. Если вы занимаетесь компьютерной графикой, то дисковое пространство, скорее всего, позволит вам записать на диск несколько тысяч мелких *.jpg. Я записывал их во временную директорию и потом верстал для печати в листы (тоже скриптами).

Функция для нумерования карточек у нас уже есть, теперь нужна функция для создания самого рисунка и записи результата в файл.
Загружаем подготовленный рисунок, выделяем картинку [Ctrl+A]. Копируем рисунок в буфер обмена [Ctrl+C] и закрываем файл с подложкой. В очередной раз убиваем файлы *.log с записанными действиями и приступаем к подготовке карточки. 

Процедура очень похожа на запись Action'а — только запись ведется в соответствующий log-файл:

  1. Создаем новый файл [Ctrl+N]. "Фотошоп" сам предложит вам нужные размеры, ориентируясь на содержащийся в буфере обмена рисунок. Соглашайтесь.
  2. Вставляем рисунок [Ctrl+V].
  3. Создаем в нашем скрипте новую функцию create_card() и вставляем в нее текст из свежезаписанного ScriptingListe-nerJS.log, затем снова жестоко расправляемся с логом.
  4. Теоретически на этом месте должна происходить вставка номера карточки, но мы вставим его позже — прямо в скрипт.
  5. Склеиваем слои: Layer / Flatten Image.
  6. Записываем файл на диск: File/Save as... Файл записываем в формате JPEG под именем tmp.jpg.
  7. Закрываем файл [Ctrl+W].
  8. В очередной раз заглядываем в ScriptingListenerJS.log и вставляем его содержимое в новую функцию com-plete_file(number) {…} (на место многоточия).
  9. В новой функции меняем строчку, определяющую имя записываемого файла: вместо ""c:\temp\tmp.jpg"" подставляем ""//temp/"+number+".jpg"".

Большая часть работы проделана. Давайте проверим наш скрипт — вставим в его начало вызовы записанных функций и запустим на выполнение:

create_card();
insert_number(115);
complete_file(115);

Работает? Да. Неправильно? Ну еще бы. Ведь для корректного исполнения в буфере обмена должен содержаться рисунок с подложкой (фоновым рисунком), а мы заполнили буфер фрагментами текста скрипта. Можно перед запуском скрипта ручками загрузить фон, скопировать его в буфер и отдать руль программе — пусть едет. Однако, если этот скрипт еще когда-нибудь вам понадобится, лучше сразу все в нем записать:

  1. Чистим лог (удаляем *.log-файлы с записями).

  2. Открываем файл с подложкой [Ctrl+O].
  3. Выделяем все [Ctrl+A].
  4. Копируем рисунок в буфер обмена [Ctrl+C].
  5. Закрываем рисунок [Ctrl+W].
  6. Содержимое лога без изменений переносим в новую функцию initialize_script(). Впрочем, одно изменение понадобится: имя файла с подложкой "C:\temp\tmp.jpg" для корректной работы следует записать как "//temp/tmp.jpg".

Теперь наш скрипт приобретает следующий вид:

initialize_script();
create_card();
insert_number(115);
complete_file(115);

За этими строчками, естественно, следует описание вызываемых функций. Если теперь запустить написанное, то на выходе мы получим файл "115.jpg" в каталоге "c:\temp\", в котором будет записана наша картина вместе с красивой надписью "00115".

Остались пустяки: наштамповать продукцию с разными номерами. Меняем текст программы:

initialize_script();
for (number=1;number< 1001 ;number++)
{
create_card();
insert_number(number);
complete_file(number);
}

Результатом работы скрипта станет тысяча файлов с названиями от 1.jpg до 1000.jpg в директории c:\temp\.

Думаю, стоит вставить несколько замечаний о граблях, по которым я прогулялся при создании скрипта:

  • JavaScript различает строчные и прописные буквы в именах функций. Следите за синтаксисом.
  • JavaScript иногда не понимает двойных кавычек при обработке строк. Я бился над отладкой скрипта полчаса — пока не заметил, что ошибка возникает в строчках, где идет работа с текстами.
  • "Фотошоп" записывает имена файла в формате, родном для операционной системы: "c:\temp\temp.jpg", а сам использует записи в юниксовом стиле: "//temp/temp.jpg". Не забудьте внести в свои скрипты для записи/чтения файлов необходимые изменения.
  • Противная мелочь, которая иногда портит кровь: не забывайте ставить скобки за именем функции, даже если она не имеет параметров: initialize_script() будет работать, а initialize_script выдаст ошибку.
  • Пока скрипт работает, нельзя пользоваться буфером обмена, иначе "Фотошоп" погонит брак — в буфере должна быть фоновая картинка.
  • При записи картинки в JPG не выставляйте слишком высокое качесто, лучше ее посильнее сжать, иначе ваша c:\temp\ может занять несколько гигабайт.

Теперь нужно собрать отдельные картинки в листы перед распечаткой — вы ведь не станете распечатывать крохотные карточки на отдельных листах бумаги, правда? 

Самый распространенный размер — А4 (297x210 мм). На таком листе поместится 8 наших карточек в прямоугольнике 20x28 см.

Создаем в "Блокноте" новый текстовый файл и записываем его как "layout.js". В нем прописываем функцию open_file (number) для загрузки картинки с нужным номером: действия и изменения текста функции аналогичны тому, что мы делали для записи файла при создании функции complete_file(number).

В скрипте пропишем два вложенных цикла: первый для перебора верстаемых страниц, второй — для входящих в состав страницы карточек:

for (page=1;page<11;pa-ge++) — здесь сверстается 10 страниц
{
create_page();
for (number=1;number <9;number++) — здесь загрузится 8 карточек
open_file((page-1)*8+number);
make_layout();
save_page(page);
}

Результатом работы будут 10 сверстанных страниц с карточками. Здесь вы видите три вызова функций, которые в новом скрипте пока отсутствуют:

create_page() — создает новый документ "Фотошоп" размером 20х28 см. Вы можете воспользоваться функциями "Фотошопа", описанными в справочной документации по скриптам, либо записать функцию тем же способом, которым мы создавали предыдущие. Имя страницы для начала лучше оставить таким, какое "Фотошоп" дает по умолчанию новому документу, — "Untitled-1".

save_page(page) — запись на диск готовой к печати страницы. Функция практически идентична записи файла на диск из предыдущего скрипта. Имя файла я задал как ""//temp/page_"+page+".jpg"".

make_layout() — верстает карточки в один лист. На этой процедуре следует задержаться, так как есть некоторые мелочи, без которых будет сложно добиться создания правильно работающей функции.

Обратите внимание: страница создается до того, как мы начинаем загружать изображения карточек. После этого "Фотошоп" загружает картинки. Я верстал их следующим образом:

  1. Создаем картинку 20х28 см с тем же разрешением, с которым рисовали карточки (или вызываем функцию create_page()).

  2. Загружаем первые восемь карточек.

  3. Чистим лог.

  4. Повторяем восемь раз (по числу карточек на листе) следующую процедуру:

    • Щелкаем правой кнопкой мыши по единственному слою текущего документа в палитре Layers и в появившемся меню выбираем пункт Duplicate Layer.

    • В диалоговом окне указываем, куда дублировать слой: Destination — document: Un-titled-1: — это страница, которую мы готовим к печати.

    • Закрываем текущий документ

    [Ctrl+W].
  5. Теперь у нас есть лист 20х28 с восемью карточками на нем. Их нужно разместить на листе. Заходим в настройки [Ctrl+K] раздел Guides, Grid & Slices. Здесь нужно выставить шаг сетки 1 см. Закрываем окно настроек и включаем сетку [Ctrl+"]. Сетка понадобится, чтобы ровно разместить карточки.

  6. Теперь выбираем инструмент перетаскивания [V] и перетягиваем первую карточку на новое место — туда, где она должна быть при печати. Дайте попробую угадать — у вас это левый верхний угол:). Теперь нужно нажать клавиши Alt+[, чтобы перейти к предыдущему слою. Выбирать мышкой слой нежелательно, так как "Фотошоп" воспримет это не как "выбор предыдущего слоя", а как "выбор слоя с именем…" — того, на который вы указали мышью: операция будет верна для данного случая, но совсем не обязательно захочет работать в скрипте.

  7. Повторите нужное количество раз пункт №6.

  8. Склейте слои: Image/ Flatten Image.

  9. Подгоните размер картинки под размеры листа бумаги (это можно и не делать — зависит от того, как и где вы собираетесь печатать результаты своей работы). Делается это так: Image/Canvas size.

  10. Скопируйте содержимое лога и вставьте в функцию make_layout().

Вот, собственно, и все. Запускаем скрипт и идем пить кофе. Человек отдыхает, машина работает — для этого ее и создали.

Если у кого-нибудь из читателей есть вопросы по реализации той или иной задачи по работе с графикой — пишите на мой адрес: Lecosson@mail.ru, а я по мере возможности буду отвечать письмом или статьей. 

Всего вам хорошего.

На главную страницу