Скрипт Adobe After Effects для импорта файлов PNG в виде слоев

Я ищу способ импортировать созданные Photoshop слои в After Effects. Проблема в том, что наш проект требует, чтобы мы экспортировали слои как отдельные файлы из Photoshop, а затем импортировали эти файлы в After Effects. При огромном количестве слоев и сцен с этим невозможно справиться вручную. Я ищу сценарий или способ написать его для автоматизации этого процесса. Сценарий должен взять расположение слоев в исходном файле Photoshop и поместить соответствующие файлы PNG в проект After Effects в тех же местах.

В этом видео в 4:30 парень начинает использовать инструмент, который управляет автоматизацией, которую я описал. .

Любая идея, как я могу получить в свои руки такой сценарий?


person OwlOnMoon    schedule 17.11.2019    source источник


Ответы (1)


Следующий код работает на данный момент для меня. Надеюсь, он послужит вам отправной точкой. Пожалуйста, позвольте мне добавить некоторые примечания к некоторым строкам:

1- files — это папка, в которой скрипт будет искать слои. Это должна быть папка рядом с вашим проектом .aep (или соответствующим образом измените эту строку).

10-46- Инициализация некоторых полезных функций, например, для получения номера элемента папки или композиции на основе ее имени. Они добавляются на случай, если вы захотите заменить жестко заданные значения (я не смог этого сделать из-за нехватки времени).

Также обратите внимание, что в строках 55, 68, 69 или 72 жестко закодирован номер элемента композиции/папки. Это означает, что этот сценарий будет работать до тех пор, пока в вашем проекте After Effects первый элемент — это композиция, а второй – папка.

В строке 58 предлагается ввести текстовый файл с именами и позициями слоев.

Я думаю, что остальное довольно ясно из комментариев, но дайте мне знать, если у вас есть дополнительные вопросы.

var originFolder = "\\files";

var path = app.project.file.path;
var originFolderPath = Folder(path + originFolder);
var originFolderFiles = originFolderPath.getFiles();
var myProject = app.project;

// Functions to handle the importing of files and folders

function processFile(theFile) {
    try {
        var importOptions = new ImportOptions(theFile);
        importSafeWithError(importOptions);
    } catch (error) { 
    }
}

function importSafeWithError(importOptions) {
    try { 
        app.project.importFile(importOptions);
    } catch (error) {
        alert(error.toString() + importOptions.file.fsName, scriptName);
    }
}
function processFolder(folder) {
    var filesInFolder = folder.getFiles();
    for (index in filesInFolder) {
        if (filesInFolder[index] instanceof File) {
            processFile(filesInFolder[index]); 
        }
    }   
}
function getFolderByName(folderName) {  // Given a folder name, returns the item index in the project
    for (var i = 1; i <= myProject.numItems; i++) {
        if ((myProject.item(i) instanceof FolderItem) && (myProject.item(i).name == folderName)){
            return myProject.item(i);
        }
    }
}
function getCompByName(compName) {  // Given a folder name, returns the item index in the project
    for (var i = 1; i <= myProject.numItems; i++) {
        if ((myProject.item(i) instanceof CompItem) && (myProject.item(i).name == compName)){
            return myProject.item(i);
        }
    }
}


// Fun starts here

processFolder(originFolderPath); // Import the files of the folder originFolder

for (var i = 1; i <= myProject.numItems; i++) {  // Put the imported files inside item(2) --> folder
    if (myProject.item(i) instanceof FootageItem) {
        myProject.item(i).parentFolder = myProject.item(2); // Note that the folder must be item(2)
    }
} 
var textFile = File.openDialog("Select text file."); // select the text file you want to open
if (textFile != null){
    textFile.open("r"); 
}
var text;
while (!textFile.eof){
    text = textFile.readln();
}
var textArr = text.split(', '); // Separate the different values in an array

for (var i = 1; i <= myProject.item(2).numItems; i++){   // Add the layers to the comp
    myProject.item(1).layers.add(myProject.item(2).item(i)); // Note that the comp must be item(1)
} 

comp = myProject.item(1); // Setting the comp that contains our layers

for (var i = 1; i<= comp.numLayers; i++){ // Flipping the layer order so Layer 1 is the first one
    comp.layer(i).moveToBeginning();
}

u = 0;
for (var i = 1; i <= comp.numLayers; i++){ // Setting the position of each layer
    u = u+3;    // Skipping every 3rd item to ignore the "Layer X" values on the txt file
    var posArr = [0,0]; // Create a new array for the position of the layer
    origX = parseInt(u-2); // Select the appropiate item of the array, skipping "Layer X"
    origY = parseInt(u-1);
    posArr[0] = textArr[origX];
    posArr[1] = textArr[origY];
    layer = comp.layer(i);
    layer.property("Position").setValue(posArr); // Applying the new X,Y array to the position value
}

Вам нужно сохранить исходную точку привязки каждого слоя? Потому что было бы легко сделать следующее:

(Photoshop) Файл > Экспорт > Слои в файлы...

И сохраните каждый слой в формате png размером с холст. Затем пакетно импортируйте его в композицию с помощью скрипта After Effects. Проблема в том, что все опорные точки будут в центре композиции, что, как я предполагаю, не очень хорошо для вас.

Другой альтернативой может быть прямой импорт PSD-файла в After Effects. Если вы импортируете файл PSD как композицию вместо видеоряда и выбираете «Сохранить размер слоя», вы получите каждый слой PSD в слое After Effects и правильно расположите его. Это не вариант для вашего варианта использования?

person sqr    schedule 20.11.2019
comment
Да, проблема в том, что мой проект требует импорта PNG в After Effects, а не PSD с сохранением размера слоя. Так что нет, это не мой вариант. Я ищу скрипт для пакетного импорта с сохранением позиций и размеров. Я написал скрипт, который извлекает координаты слоев в PSD, а затем экспортирует слои PNG. Теперь мне нужна вторая часть. Спасибо! - person OwlOnMoon; 20.11.2019
comment
Я думаю, что мог бы помочь вам со второй частью, так как я уже делал что-то очень похожее ранее. Где вы храните координаты каждого слоя? - person sqr; 20.11.2019
comment
В текстовом файле, где каждый слой имеет свои x и y в виде значений, разделенных запятыми. - person OwlOnMoon; 20.11.2019
comment
вы включаете имя слоя в txt или только значения X, Y каждого слоя? Если вы можете предоставить образец txt, я, вероятно, смогу предоставить вам код, который работает из коробки с дополнительными эффектами для обработки импорта. - person sqr; 22.11.2019
comment
Да было бы здорово! Я включаю имена, и вот как это выглядит: Слой 2,1125,169 Слой 1,87,327 Фон,0,0 - person OwlOnMoon; 22.11.2019
comment
@OwlOnMoon Я отредактировал свой первоначальный ответ с помощью сценария, он не помещался в разделе комментариев. - person sqr; 25.11.2019
comment
Да, я сам придумал подобный скрипт, и он работает. Но все равно спасибо, отмечу правильно. - person OwlOnMoon; 25.11.2019