Exportar em lote as camadas do Photoshop para arquivos PNG individuais

130

Sou desenvolvedor da Web e competente no Fireworks, mas não tanto no Photoshop.

Acabei de receber um arquivo PSD em camadas para virar uma página da web. Alguém pode me dizer a maneira mais fácil de exportar todas as camadas para arquivos png individuais?

Existem muitas camadas e fazer isso manualmente parece errado.

Eu já vi isso, mas parece que deve haver funcionalidade nativa para isso no PS.

Eu tenho acesso ao Photoshop CS4. Qualquer ponteiro apreciado.

user256888
fonte
Existe alguma maneira de evitar que os .pngs sejam transformados no modo de índice? Eu preciso deles RGB. Provavelmente eu poderia criar apenas uma gota, mas não sabia se havia uma maneira mais fácil ... Obrigado pela dica, isso é ótimo!
O convertcomando free do Imagemagick pode ser usado para isso (pode não ter cobertura completa dos recursos do psd).
Uriel

Respostas:

158

Método 1: o script interno da Adobe

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

insira a descrição da imagem aqui

Aqui estão algumas perguntas relacionadas ...

Exportando camadas individuais no Photoshop, mantendo seus tamanhos

Exportar camadas para arquivos exporta apenas 4 arquivos png de 100 camadas


Método 2: Script personalizado

Passei algum tempo e escrevi meu próprio arquivo de script para automatizar esse processo. Esse processo é muito mais rápido que o script interno mencionado acima.

Obtenha o script agora no Github!

informação adicional

Eu executei esse script em um arquivo de 100 camadas e 450 MB em menos de 60 segundos. A execução do script interno no mesmo arquivo leva cerca de 30 minutos.

Ao testar com grupos de camadas de ninho, descobri que meu script é executado em cerca de 90 segundos, enquanto o script interno leva cerca de 27 minutos (e na verdade exporta errado).

Observe que esses resultados variam dependendo das complexidades dos arquivos, bem como do hardware do seu computador e da versão do Photoshop. Dados de desempenho adicionais .

Este script (nos últimos anos) obteve várias melhorias de vários colaboradores. Se você tiver algum problema com o script. Você pode arquivar problemas com o script aqui .

Leia o leia-me para obter mais informações adicionais.

Isenção de responsabilidade: este script não está associado à Adobe de forma alguma. Por favor, use o script por sua conta e risco - sempre faça um backup do seu PSD antes de usá-lo. Não sou responsável por dados danificados ou perdidos.

Hanna
fonte
11
@ Lucian - se você estiver usando o Photoshop CC, poderá fazer isso de outra forma, arquivar um problema no Github . Obrigado!
Hanna
Johannes criou um roteiro incrível para esta pergunta e deve merecer um voto positivo várias vezes, mas não procure apoio nos comentários. Se você tiver um problema com isso, procure uma solução no repositório para que eles possam ser rastreados de acordo.
DᴀʀᴛʜVᴀᴅᴇʀ
Relatórios a partir de 2018. Esta ferramenta está agora em File -> Export -> Layers to Files...
akinuri
Caso alguém fique confuso, esse é um script do Photoshop e, portanto, é necessário o Photoshop. Eu pensei que seria um script de shell. :)
Chris Rae
11
@Hanna estes são épicos !! Bom trabalho e obrigado!
Chris Emerson
18

Atualizei a solução de Johannes de um ano atrás com muitas melhorias. Significativamente:

  • Agora, os grupos de camadas são manipulados adequadamente para que todas as camadas sejam gravadas.
  • Os nomes dos arquivos são incrementados automaticamente para evitar colisões (isso acontece quando mais de uma camada tem o mesmo nome).
  • O desempenho é aumentado. O script pode salvar 500 camadas simples em alguns minutos.

Além disso, o código foi limpo. Por exemplo, variáveis ​​globais foram integradas em uma única matriz.

Observe que a mensagem pop-up inicial informa apenas o número de camadas de nível superior . Isso é para evitar a degradação do desempenho. Eu realmente não consigo imaginar um caso em que você não saiba nada sobre o arquivo com o qual está lidando, portanto isso não deve ser um grande comprometimento.

Pegue o script aqui . Obrigado ao autor anterior por liderar o caminho.

escalation746
fonte
Muito bem feito em manter este script. Ele trabalhou extremamente bem exportar algum tempo caducidade correções em milhares de camadas :)
iwasrobbed
7

O CRÉDITO VAI A JOHANNES POR CONTRIBUIR O ARQUIVO. MUITO OBRIGADO!

Eu adicionei uma função que me ajudou a acessar meu arquivo de camada 2448 em cerca de 3 horas.

Aqui está o link para o arquivo modificado Download aqui

Mike June Bug Capitão
fonte
6

Atualizei o script para usar o BackgroundLayer principal do documento. Para que cada jpg que exporte seja compilado com ele.

Seria ótimo se alguém adicionasse marcação às camadas para torná-las camadas mestre em vez do padrão BackgroundLayer ;-)

script completo:

    // 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();
Arturino
fonte