Автоматизация поворота изображения в Photoshop с помощью JavaScript

Источник: habrahabr

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

Первое, что пришло в голову: php-скрипт с использованием imagerotate из библиотеки GD. Получается, прямо скажем, несколько не то, что хотелось. Пояснить проще на примере:

 Таким образом, при повороте, изображение у нас получается больше, чем исходное. Делая подобную операцию в Photoshop (Free Transform), мы избегаем этой проблемы. Скорее всего решение нашлось бы и при использовании GD, но давно хотелось попробовать автоматизировать некоторые операции в Photoshop.

 Итак, необходимо автоматизировать операцию поворота и запись в файл.

Исходная картинка - компас со стрелкой:                                  Стрелка в отдельном слое и нужно получить 360 изображений этой стрелки.

                                                                                                                                                                                                                                

 Для бОльшей универсальности усложним скрипт - сделаем возможность не только записывать в отдельный файл каждый поворот, но и делать одно широкое изображение. Примерно так:

 

 

 Фотошоп у меня старенький, CS1, поэтому скрипт для него. Впрочем, под CS2 пойдет без проблем, а под более старшие версии допилить труда не составит. Комментарии в коде, примеры в конце.

Код:

// Устанавливаем значения
var Angle=360;  // На сколько градусов поворачиваем
var Frames=360;    // Количество кадров. Автоматически подсчитывается на сколько градусов нужно повернуть каждый кадр.
var saveFile = 1;  // Запись в файл каждого отдельного изображения: 0 - пишем в файл, 1 - не пишем
var Negative="";     // Если нужно крутить против часовой стрелки, то ставим минус

if (app.documents.length > 0) {
   
    // Определяем размеры текущего изображения
    app.preferences.rulerUnits = Units.INCHES;
    var srcDoc = app.activeDocument;
    var x2 = srcDoc.width * srcDoc.resolution;
    var y2 = srcDoc.height * srcDoc.resolution;

    // Выделяем все
    srcDoc.selection.select(Array (Array(0, 0), Array(x2, 0), Array(x2, y2), Array(0, y2)), SelectionType.REPLACE, 0, false);
    // Копируем выделенное
    srcDoc.selection.copy();

    // Создаем новый документ аналогичного размера, если каждый файл пишем отдельно.
    // Или документ нужной ширины, если всем делаем в одном файле
    app.preferences.rulerUnits = Units.PIXELS;
    var iFrames = 1;
    if (saveFile == 1) {
        iFrames = Frames;
    }
    var pasteDoc = app.documents.add(Number(x2*iFrames), Number(y2), srcDoc.resolution, "Rotated Layers", NewDocumentMode.RGB, DocumentFill.TRANSPARENT);

    // Выделяем все
    pasteDoc.selection.select(Array (Array(0, 0), Array(x2, 0), Array(x2, y2), Array(0, y2)), SelectionType.REPLACE, 0, false);
    // Вставляем изображение из буфера
    pasteDoc.paste();
    layerRef = pasteDoc.layers[0];
    // Самое главное - поворачиваем выделенное на количество градусов разделенных на количество картинок, которое нам нужно получить
    Angle = Angle / Frames;
    if (saveFile == 0) {
        // записываем в файл
        SaveToFile('0');
        // Не нашел как удалить слой в CS1, поэтому просто делаем слой невидимым
        layerRef.visible = false;
    }
    // Повторяем операцию нужное количество раз
    for ( var i = 1; i < Frames; i++ ) {
        var xs = x2 * i;
        pasteDoc.selection.select(Array (Array(xs, 0), Array(xs+x2, 0), Array(xs+x2, y2), Array(xs, y2)), SelectionType.REPLACE, 0, false);
        pasteDoc.paste();
        layerRef = pasteDoc.layers[0];
        layerRef.rotate(Negative + Angle*i);
        if (saveFile == 0) {
            SaveToFile(i);
            layerRef.visible = false;
        }
    }

} else {
    alert("Надо открыть хоть какое-нибудь изображение");
}  
   
function SaveToFile(n) {

    // Путь к файлу и имя файла. Нужно обратить внимание на регистр и слэши.
    var saveFile = new File("C:/test/"+n+".png");
    pngSaveOptions = new PNGSaveOptions();
    app.activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);

}

Как пользоваться:

Называем файл скрипта, например Rotate.js и помещаем его в каталог фотошопа: Photoshop\Presets\Scripts\
Редактируем параметры.
Открываем изображение, которое нужно обработать и в меню File->Scripts выбираем скрипт Rotate.

Демо. Картинка кликабельна. Жмем на стрелку - она крутится. В данном примере использован метод создания одного большого изображения. По мере вращения, картинка в цикле сдвигается на нужное количество пикселей, имитируя плавное вращение стрелки.

 Планировал сделать один большой PNG высотой 110px и шириной 39600px, но Firefox и Chrome отказались отображать его (IE8, Opera и Safari - смогли). Пришлось поделить на две части. Каждая часть получилась весом примерно по 620Кб.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=27991