Первые шаги в скриптинге для Фотошопа

Писать скрипты для Фотошопа, зачастую, нудно и больно (привет многочисленным багам и индийским разработчикам). Но бывает увлекательно и полезно. А если вы знакомы с JavaScript, то и достаточно легко.

Подготовка

Вам понадобится программа Adobe ExtendScript Toolkit, ваш Фотошоп и немного усердия.

После установки запускаем ExtendScript Toolkit и в левом-верхнем углу меняем «ExtendScript Toolkit CC» из выпадающего меню на Фотошоп. Делаем это для того, что бы по нажатию зелёной стрелочки наш скрипт запускался в Фотошопе.

Мы готовы. Весь код, который будет идти дальше, можно писать и выполнять в свежеустановленном ExtendScript Toolkit, а по-окончанию сего действа — сохранить в файл .jsx и пользоваться в своё удовольствие.

Не будем вникать в объектную модель Фотошопа и прочие сложные термины, про которые вы сможете прочитать в официальной документации (даже с картинками). Ссылки есть в конце поста.

В бой.

Работа с активным слоем

Чаще всего мы хотим что-либо сделать с активным слоем. Для этого необходимо обратиться к Фотошопу (app), затем к активному документу (activeDocument) и, наконец, к нашему слою (activeLayer).

app.activeDocument.activeLayer

У слоя есть свойства и методы (выполняемые действия), как и у остальных объектов (документов, каналов, текста, векторных шейпов, …).

Например, что бы узнать имя слоя — нужно обратиться к свойству name.

alert(app.activeDocument.activeLayer.name); // Покажет окно с именем активного слоя

А что бы переименовать слой:

app.activeDocument.activeLayer.name = 'Мой любимый слой';

Скрыть или показать слой — свойство visible.

app.activeDocument.activeLayer.visible = false; // true

Подвигать содержимое слоя по холсту — метод translate.

app.activeDocument.activeLayer.translate(X, Y);

А так же можно узнавать границы содержимого (bounds), изменять прозрачность слоя (opacity) и заливки (fillOpacity), дублировать (duplicate), масштабировать (resize) и так далее.

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

Усложняем задачу

Допустим, у нас есть документ с текстовым слоем (в нём что-то написано).

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

// Узнаём цвет
var textColor = app.activeDocument.activeLayer.textItem.color.rgb.hexValue;
// Шрифт
var textFont = app.activeDocument.activeLayer.textItem.font;
// Размер шрифта
var textSize = app.activeDocument.activeLayer.textItem.size;
// Переименовываем слой
app.activeDocument.activeLayer.name = textFont+', '+textSize+', #'+textColor;

После выполнения такого скрипта имя нашего слоя превратится в нечто подобное:

ArialMT, 14 pt, #000000

Или ничего не произойдёт, так как мы можем встретиться с нашим первым багом Фотошопа. ☺

Дело в том, что если создать новый текстовый слой и не изменять ему цвет, а оставить дефолтный чёрный (#000000), то по какой-то причине Фотошоп не может получить это значение. Подобный баг далеко не единственный, но, зачастую, они побеждаются довольно легко — при помощи javascript-конструкции try…catch. Данная синтаксическая конструкция пытается выполнить кусок кода прописанный в try, а если возникает ошибка — выполняет кусок кода из catch. Подробнее про try…catch на сайте javascript.ru.

try {
    // ваш код
} catch(e) {
    // код выполняемый в случае ошибки в блоке try
}

Итак, фиксим возможную ошибку с определением цвета:

try {
    var textColor = app.activeDocument.activeLayer.textItem.color.rgb.hexValue;
} catch(e) {
    var textColor = '000000';
}

Получаем следующее:

try {
    var textColor = app.activeDocument.activeLayer.textItem.color.rgb.hexValue;
} catch(e) {
    var textColor = '000000';
}

var textFont = app.activeDocument.activeLayer.textItem.font;
var textSize = app.activeDocument.activeLayer.textItem.size;
    
app.activeDocument.activeLayer.name = textFont+', '+textSize+', #'+textColor;

Теперь наш код точно сработает.

Это уже что-то похожее на нужный результат, но мы пойдём дальше и добавим ещё немного магии.

Ниже финальная версия скрипта в которой я предлагаю вам разобраться самостоятельно.

// Складываем в переменную наш слой для более компактного кода,
// дабы каждый раз не повторять эту длинную строчку
var myLayer = app.activeDocument.activeLayer;
// Проверяем текстовый это слой или какой-то другой
if (myLayer.kind == 'LayerKind.TEXT') {
    // Получаем цвет текста, фиксим баг и добавляем запятую
    try{
        var textColor = ', #'+myLayer.textItem.color.rgb.hexValue;
    } catch(e) {
        var textColor = ', #000000';
    }
    // Получаем интерлиньяж и опять фиксим баг,
    // а если интерлиньяж имеет значение auto (получаем баг),
    // то ничего не пишем в имени слоя
    try{
        var textLineHeight = '/'+parseInt(myLayer.textItem.leading)+'px';
    } catch(e) {
        var textLineHeight = '';
    }
    // Узнаём привычное системное имя шрифта, 
    // а не PostScript-имя, которое он нам возвращал раньше
    var textFont = app.fonts.getByName(myLayer.textItem.font).name;
    
    // Берём числовое значение без pt, добавляем px и запятую
    var textSize = ', '+parseInt(myLayer.textItem.size)+'px';
 
    myLayer.name = textFont + textSize + textLineHeight + textColor;
}

В итоге, имя нашего слоя превратится в нечто похожее:

Arial Bold Italic 30px/40px #333000

или

PT Sans 18px #ff0000

Полезные материалы

Раньше
Скрипт для автоматического обновления смарт-объектов
Позже
УберФейсы — генератор случайных пользователей