Пакетний експорт шарів Photoshop в окремі файли PNG


130

Я веб-розробник і компетентний у феєрверках, але не так багато у Photoshop.

Щойно я отримав шаруватий файл PSD, який перетворився на веб-сторінку. Хтось може сказати мені найпростіший спосіб експорту всіх шарів до окремих png-файлів?

Є багато шарів, і робити це вручну здається неправильним.

Я бачив це, але, здається, для PS в цьому має бути нативна функціональність.

У мене є доступ до Photoshop CS4. Будь-які вказівники оцінили.


Чи є спосіб уникнути перетворення .pngs у режим індексу? Мені потрібні RGB. Я, мабуть, міг просто створити для цього крапельку, але не знав, чи є простіший спосіб ... Дякую за пораду, хоча це чудово!

Для convertцього може бути використана вільна команда від Imagemagick (можливо, вона не матиме повного покриття функцій psd).
Уріель

Відповіді:


158

Спосіб 1: Вбудований сценарій від Adobe

File >> Scripts >> Export layers to files...

введіть тут опис зображення

Ось кілька пов'язаних питань ...

Експорт окремих шарів у Photoshop, зберігаючи їх розміри

Експорт шарів у файли експортує лише 4 png-файли зі 100 шарів


Спосіб 2: Спеціальний сценарій

Я витратив деякий час і написав власний файл сценарію для автоматизації цього процесу. Цей процес відбувається набагато швидше, ніж вбудований сценарій, згаданий вище.

Отримайте сценарій зараз на Github!

Додаткова інформація

Я запустив цей скрипт на 100-шаровий, 450 Мб файл, за менше 60 секунд. Запуск вбудованого сценарію в одному файлі займає 30 хвилин.

Під час тестування з групами шарів гнізд я виявив, що мій сценарій працює приблизно за 90 секунд, тоді як вбудований сценарій займає близько 27 хвилин (і насправді його неправильно експортують).

Зауважте, що ці результати будуть різними залежно від складності файлів, а також обладнання на вашому комп'ютері та версії Photoshop. Додаткові дані про ефективність .

Цей сценарій (за останні кілька років) отримав різні вдосконалення від різних учасників. Якщо у вас виникли проблеми зі сценарієм. Ви можете подати проблеми зі сценарієм тут .

Будь ласка, прочитайте читання за будь-якою додатковою інформацією.

Відмова: Цей сценарій жодним чином не асоціюється з Adobe. Будь ласка, використовуйте скрипт на свій страх і ризик - перед використанням завжди створюйте резервну копію PSD. Я не несу відповідальності за будь-які пошкоджені або втрачені дані.


1
@Lucian - якщо ви використовуєте Photoshop CC, ви можете зробити це інакше, подайте проблему на Github . Дякую!
Ганна

Йоханнес склав приголомшливий сценарій цього питання, і він справедливо заслуговує на виплату пропозицій кілька разів, але, будь ласка, не шукайте підтримки для цього в коментарях. Якщо у вас є проблеми з цим, будь ласка, шукайте рішення через репо, щоб вони могли бути відстежені відповідно.
DᴀʀᴛʜVᴀᴅᴇʀ

Репортаж з 2018 року. Цей інструмент заразFile -> Export -> Layers to Files...
нижче,

Якщо хтось заплутається, це сценарій Photoshop і тому потрібен Photoshop. Я думав, що це буде сценарій оболонки. :)
Chris Rae

1
@Hanna це EPIC !! Приємної роботи і дякую!
Кріс Емерсон

18

Рішення Йоганнеса я оновив рік тому з багатьма вдосконаленнями. Значно:

  • Групи шарів тепер обробляються належним чином, щоб усі шари були записані.
  • Імена файлів автоматично збільшуються, щоб запобігти зіткненням (це відбувається, коли більше одного шару має те саме ім’я).
  • Продуктивність збільшується. Сценарій може заощадити 500 простих шарів за кілька хвилин.

Крім цього, код був очищений. Наприклад, глобальні змінні інтегровані в єдиний масив.

Зауважте, що початкове спливаюче повідомлення повідомляє лише про кількість шарів верхнього рівня . Це уникає погіршення продуктивності. Я не можу уявити собі випадок, коли ви нічого не знаєте про файл, з яким ви маєте справу, тому це не повинно бути великим компромісом.

Візьміть сюди сценарій . Дякуємо попередньому автору за провідний шлях.


Дійсно молодець у підтримці цього сценарію. Він працював надзвичайно добре, експортуючи певні виправлення виправлень на тисячі шарів :)
iwasrobbed


6

Я оновив сценарій, щоб використовувати основний BackgroundLayer документа. Так що кожен jpg, який експортується, компілюється з ним.

Було б чудово, якби хтось додав теги до шарів, щоб зробити їх Master шарами замість за замовчуванням BackgroundLayer ;-)

повний сценарій:

    // NAME: 
//  SaveLayers

// DESCRIPTION: 
//  Saves each layer in the active document to a PNG or JPG file named after the layer. 
//  These files will be created in the current document folder (same as working PSD).

// REQUIRES: 
//  Adobe Photoshop CS2 or higher

//Most current version always available at: https://github.com/jwa107/Photoshop-Export-Layers-as-Images

// enable double-clicking from Finder/Explorer (CS2 and higher)
#target photoshop
app.bringToFront();

function main() {
    // two quick checks
    if(!okDocument()) {
        alert("Document must be saved and be a layered PSD.");
        return; 
    }

    var len = activeDocument.layers.length;
    var ok = confirm("Note: All layers will be saved in same directory as your PSD.\nThis document contains " + len + " top level layers.\nBe aware that large numbers of layers may take some time!\nContinue?");
    if(!ok) return

    // user preferences
    prefs = new Object();
    prefs.fileType = "";
    prefs.fileQuality = 12;
    prefs.filePath = app.activeDocument.path;
    prefs.count = 0;

    //instantiate dialogue
    Dialog();
    hideLayers(activeDocument);
    saveLayers(activeDocument);
    toggleVisibility(activeDocument);
    alert("Saved " + prefs.count + " files.");
}

function hideLayers(ref) {
    var len = ref.layers.length;
    for (var i = 0; i < len; i++) {
        var layer = ref.layers[i];
        if (layer.typename == 'LayerSet') hideLayers(layer);
        else layer.visible = false;
    }
}

function toggleVisibility(ref) {
    var len = ref.layers.length;
    for (var i = 0; i < len; i++) { 
        layer = ref.layers[i];
        layer.visible = !layer.visible;
    }
}

function saveLayers(ref) {
    var len = ref.layers.length;
    // rename layers top to bottom
    for (var i = 0; i < len; i++) {
        var layer = ref.layers[i];
        if (layer.typename == 'LayerSet') {
            // recurse if current layer is a group
            hideLayers(layer);
            saveLayers(layer);
        } else {
            // otherwise make sure the layer is visible and save it
            layer.visible = true;

    // NEW MASTER BACKGROUND LAYER -- comment this line if u dont want to see that layer compiled in the jpgs
       activeDocument.backgroundLayer.visible = true;

    saveImage(layer.name);

     layer.visible = false;
        }
    }
}

function saveImage(layerName) {
    var fileName = layerName.replace(/[\\\*\/\?:"\|<> ]/g,''); 
    if(fileName.length ==0) fileName = "autoname";
    var handle = getUniqueName(prefs.filePath + "/" + fileName);
    prefs.count++;

    if(prefs.fileType=="PNG" && prefs.fileQuality=="8") {
        SavePNG8(handle); 
    } else if (prefs.fileType=="PNG" && prefs.fileQuality=="24") {
        SavePNG24(handle);
    } else {
        SaveJPEG(handle); 
    }
}

function getUniqueName(fileroot) { 
    // form a full file name
    // if the file name exists, a numeric suffix will be added to disambiguate

    var filename = fileroot;
    for (var i=1; i<100; i++) {
        var handle = File(filename + "." + prefs.fileType); 
        if(handle.exists) {
            filename = fileroot + "-" + padder(i, 3);
        } else {
            return handle; 
        }
    }
} 

function padder(input, padLength) {
    // pad the input with zeroes up to indicated length
    var result = (new Array(padLength + 1 - input.toString().length)).join('0') + input;
    return result;
}

function SavePNG8(saveFile) { 
    exportOptionsSaveForWeb = new ExportOptionsSaveForWeb();
    exportOptionsSaveForWeb.format = SaveDocumentType.PNG
    exportOptionsSaveForWeb.dither = Dither.NONE;



    activeDocument.exportDocument( saveFile, ExportType.SAVEFORWEB, exportOptionsSaveForWeb );
} 

function SavePNG24(saveFile) { 
    pngSaveOptions = new PNGSaveOptions(); 
    activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE); 
} 

function SaveJPEG(saveFile) { 
    jpegSaveOptions = new JPEGSaveOptions(); 
    jpegSaveOptions.quality = prefs.fileQuality;
   activeDocument.saveAs(saveFile, jpegSaveOptions, true, Extension.LOWERCASE); 
} 

function Dialog() {
    // build dialogue
    var dlg = new Window ('dialog', 'Select Type'); 
    dlg.saver = dlg.add("dropdownlist", undefined, ""); 
    dlg.quality = dlg.add("dropdownlist", undefined, "");
    dlg.pngtype = dlg.add("dropdownlist", undefined, "");


    // file type
    var saveOpt = [];
    saveOpt[0] = "PNG"; 
    saveOpt[1] = "JPG"; 
    for (var i=0, len=saveOpt.length; i<len; i++) {
        dlg.saver.add ("item", "Save as " + saveOpt[i]);
    }; 

    // trigger function
    dlg.saver.onChange = function() {
        prefs.fileType = saveOpt[parseInt(this.selection)]; 
        // decide whether to show JPG or PNG options
        if(prefs.fileType==saveOpt[1]){
            dlg.quality.show();
            dlg.pngtype.hide();
        } else {
            dlg.quality.hide();
            dlg.pngtype.show();
        }
    }; 

    // jpg quality
    var qualityOpt = [];
    for(var i=12; i>=1; i--) {
        qualityOpt[i] = i;
        dlg.quality.add ('item', "" + i);
    }; 

    // png type
    var pngtypeOpt = [];
    pngtypeOpt[0]=8;
    pngtypeOpt[1]=24;
    dlg.pngtype.add ('item', ""+ 8 );
    dlg.pngtype.add ('item', "" + 24);

    // trigger functions
    dlg.quality.onChange = function() {
        prefs.fileQuality = qualityOpt[12-parseInt(this.selection)];
    };
    dlg.pngtype.onChange = function() {
       prefs.fileQuality = pngtypeOpt[parseInt(this.selection)]; 
    };

    // remainder of UI
    var uiButtonRun = "Continue"; 

    dlg.btnRun = dlg.add("button", undefined, uiButtonRun ); 
    dlg.btnRun.onClick = function() {   
        this.parent.close(0); 
    }; 

    dlg.orientation = 'column'; 

    dlg.saver.selection = dlg.saver.items[0] ;
    dlg.quality.selection = dlg.quality.items[0] ;
    dlg.center(); 
    dlg.show();
}

function okDocument() {
     // check that we have a valid document

    if (!documents.length) return false;

    var thisDoc = app.activeDocument; 
    var fileExt = decodeURI(thisDoc.name).replace(/^.*\./,''); 
    return fileExt.toLowerCase() == 'psd'
}

function wrapper() {
    function showError(err) {
        alert(err + ': on line ' + err.line, 'Script Error', true);
    }

    try {
        // suspend history for CS3 or higher
        if (parseInt(version, 10) >= 10) {
            activeDocument.suspendHistory('Save Layers', 'main()');
        } else {
            main();
        }
    } catch(e) {
        // report errors unless the user cancelled
        if (e.number != 8007) showError(e);
    }
}

wrapper();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.