Batch eksportuje warstwy Photoshop do pojedynczych plików PNG


130

Jestem twórcą stron internetowych i kompetentny w Fireworks, ale nie tak bardzo w Photoshopie.

Właśnie otrzymałem warstwowy plik PSD, aby zamienić się w stronę internetową. Czy ktoś może mi powiedzieć najprostszy sposób na eksport wszystkich warstw do pojedynczych plików png?

Istnieje wiele warstw i ręczne wykonanie tej czynności wydaje się nieprawidłowe.

Widziałem to, ale wydaje się, że powinna istnieć natywna funkcjonalność w PS.

Mam dostęp do Photoshopa CS4. Doceniamy wszelkie wskazówki.


Czy jest jakiś sposób, aby uniknąć zmiany pliku .pngs w tryb indeksu? Potrzebuję ich RGB. Prawdopodobnie mógłbym po prostu stworzyć dla niego kroplę, ale nie wiedziałem, czy istnieje łatwiejszy sposób ... Dzięki za wskazówkę, to jest świetne!

convertMożna do tego użyć bezpłatnego polecenia Imagemagick (może brakować pełnego zakresu funkcji psd).
Uriel

Odpowiedzi:


158

Metoda 1: Wbudowany skrypt firmy Adobe

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

wprowadź opis zdjęcia tutaj

Oto kilka powiązanych pytań ...

Eksportowanie poszczególnych warstw w Photoshopie, z zachowaniem ich rozmiarów

Eksportuj warstwy do plików eksportuje tylko 4 pliki png ze 100 warstw


Metoda 2: Skrypt niestandardowy

Spędziłem trochę czasu i napisałem własny plik skryptu, aby zautomatyzować ten proces. Ten proces jest znacznie szybszy niż wbudowany skrypt wspomniany powyżej.

Pobierz skrypt teraz na Github!

Dodatkowe informacje

Uruchomiłem ten skrypt na 100-warstwowym pliku 450 MB w mniej niż 60 sekund. Uruchomienie wbudowanego skryptu dla tego samego pliku zajmuje mi około 30 minut.

Podczas testowania z grupami warstw gniazd odkryłem, że mój skrypt działa w około 90 sekund, podczas gdy wbudowany skrypt zajmuje około 27 minut (i faktycznie eksportuje go źle).

Należy pamiętać, że wyniki te będą się różnić w zależności od złożoności plików, a także sprzętu na komputerze i wersji programu Photoshop. Dodatkowe dane dotyczące wydajności .

Ten skrypt (w ciągu ostatnich kilku lat) uzyskał różne ulepszenia od różnych autorów. Jeśli napotkasz jakiekolwiek problemy ze skryptem. Można plików problemy ze skryptem tutaj .

Proszę przeczytać read-me dla wszelkich dodatkowych, dodatkowych informacji.

Oświadczenie: Ten skrypt nie jest w żaden sposób powiązany z Adobe. Użyj skryptu na własne ryzyko - przed użyciem zawsze wykonaj kopię zapasową PSD. Nie odpowiadam za jakiekolwiek uszkodzone lub utracone dane.


1
@Lucian - jeśli korzystasz z programu Photoshop CC , możesz to zrobić inaczej, zgłoś problem na Github . Dzięki!
Hanna

Johannes napisał niesamowity skrypt dla tego pytania i powinien słusznie zasługiwać na głosowanie kilka razy, ale proszę nie szukać wsparcia w komentarzach. Jeśli masz z tym problem, poszukaj rozwiązania poprzez repozytorium, aby można je było odpowiednio śledzić.
DᴀʀᴛʜVᴀᴅᴇʀ

Raportowanie od 2018 roku. To narzędzie jest obecnieFile -> Export -> Layers to Files...
akinuri

W przypadku, gdy ktoś się myli, jest to skrypt programu Photoshop i dlatego wymaga Photoshopa. Myślałem, że to będzie skrypt powłoki. :)
Chris Rae

1
@Hanna, to są niesamowite! Dobra robota i dziękuję!
Chris Emerson

18

Zaktualizowałem rozwiązanie Johannesa rok temu z wieloma ulepszeniami. Znacząco:

  • Grupy warstw są teraz poprawnie obsługiwane, aby wszystkie warstwy zostały zapisane.
  • Nazwy plików są automatycznie zwiększane, aby zapobiec kolizjom (dzieje się tak, gdy więcej niż jedna warstwa ma tę samą nazwę).
  • Wydajność jest zwiększona. Skrypt może zapisać 500 prostych warstw w ciągu kilku minut.

Poza tym kod został wyczyszczony. Na przykład zmienne globalne zostały zintegrowane w jedną tablicę.

Pamiętaj, że początkowy komunikat wyskakujący poda tylko liczbę warstw najwyższego poziomu . Ma to na celu uniknięcie obniżenia wydajności. Naprawdę nie wyobrażam sobie przypadku, w którym nic nie wiesz o pliku, z którym masz do czynienia, więc nie powinno to stanowić większego kompromisu.

Chwyć skrypt tutaj . Podziękowania dla poprzedniego autora za prowadzenie.


Naprawdę dobrze zrobione z utrzymaniem tego skryptu. Działa bardzo dobrze, eksportując korekty z upływem czasu na tysiące warstw :)
iwasrobbed

7

KREDYT JEST DO JOHANNESA ZA WKŁADANIE PLIKU. DZIĘKUJĘ BARDZO!

Dodałem funkcję, która pomogła mi przejść przez mój plik warstwy 2448 w około 3 godziny.

Oto link do zmodyfikowanego pliku Pobierz tutaj


6

Zaktualizowałem skrypt, aby używał podstawowej BackgroundLayer dokumentu. Tak więc kompiluje się każdy eksportowany plik jpg.

Byłoby wspaniale, gdyby ktoś dodał znaczniki do warstw, aby uczynić je warstwami głównymi zamiast domyślnej warstwy tła ;-)

pełny skrypt:

    // 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();
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.