Exporte por lotes las capas de Photoshop a archivos PNG individuales

130

Soy un desarrollador web y competente en Fireworks, pero no tanto en Photoshop.

Acabo de recibir un archivo PSD en capas para convertirlo en una página web. ¿Alguien puede decirme la forma más fácil de exportar todas las capas a archivos png individuales?

Hay muchas capas y hacer esto manualmente parece incorrecto.

He visto esto, pero parece que debería haber una funcionalidad nativa para esto en PS.

Tengo acceso a Photoshop CS4. Cualquier puntero apreciado.

usuario256888
fuente
¿Hay alguna manera de evitar que los .pngs se conviertan en modo de índice? Los necesito RGB. Probablemente podría crear una gota para ello, pero no sabía si había una manera más fácil ... ¡Gracias por el consejo, esto es genial!
El convertcomando gratuito de Imagemagick podría usarse para esto (puede carecer de una cobertura completa de funciones psd).
Uriel

Respuestas:

158

Método 1: el script incorporado de Adobe

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

ingrese la descripción de la imagen aquí

Aquí hay algunas preguntas relacionadas ...

Exportar capas individuales en Photoshop, manteniendo sus tamaños

Exportar capas a archivos exporta solo 4 archivos png de 100 capas


Método 2: secuencia de comandos personalizada

Pasé un tiempo y escribí mi propio archivo de script para automatizar este proceso. Este proceso es mucho más rápido que el script incorporado mencionado anteriormente.

¡Obtén el script ahora en Github!

Información Adicional

Ejecuté este script en un archivo de 100 capas y 450 MB en menos de 60 segundos. Ejecutar el script incorporado en el mismo archivo me lleva unos 30 minutos.

Al probar con grupos de capas de anidamiento, descubrí que mi secuencia de comandos se ejecuta en aproximadamente 90 segundos, mientras que la secuencia de comandos incorporada tarda aproximadamente 27 minutos (y en realidad la exporta mal).

Tenga en cuenta que estos resultados variarán dependiendo de la complejidad de los archivos, así como del hardware de su computadora y la versión de Photoshop. Datos de rendimiento adicionales .

Este script (en los últimos años) ha recibido varias mejoras de varios contribuyentes. Si se encuentra con algún problema con el script. Puede archivar problemas con el script aquí .

Lea el archivo Léame para obtener información adicional adicional.

Descargo de responsabilidad: este script no está asociado con Adobe de ninguna manera. Utilice la secuencia de comandos bajo su propio riesgo: siempre haga una copia de seguridad de su PSD antes de usarla. No soy responsable de los datos dañados o perdidos.

Hanna
fuente
1
@Lucian: si está utilizando Photoshop CC , puede hacer esto de otra manera, presentar un problema en Github . ¡Gracias!
Hanna
Johannes ha creado un guión increíble para esta pregunta y con razón debería merecer un voto positivo varias veces, pero por favor no busque apoyo para esto en los comentarios. Si tiene un problema con esto, busque una solución a través del repositorio para que puedan rastrearse en consecuencia.
DᴀʀᴛʜVᴀᴅᴇʀ
Informes desde 2018. Esta herramienta está, ahora, bajoFile -> Export -> Layers to Files...
akinuri
En caso de que alguien más se confunda, este es un script de Photoshop y, por lo tanto, requiere Photoshop. Pensé que iba a ser un script de shell. :)
Chris Rae
1
@ Hanna estos son EPIC !! Buen trabajo y gracias!
Chris Emerson
18

He actualizado la solución de Johannes de hace un año con muchas mejoras. Significativamente:

  • Los grupos de capas ahora se manejan correctamente para que todas las capas se escriban.
  • Los nombres de archivo se incrementan automáticamente para evitar colisiones (esto sucede cuando más de una capa tiene el mismo nombre).
  • El rendimiento aumenta. El script puede guardar 500 capas simples en pocos minutos.

Además de esto, el código ha sido limpiado. Por ejemplo, las variables globales se han integrado en una sola matriz.

Tenga en cuenta que el mensaje emergente inicial solo le indicará el número de capas de nivel superior . Esto es para evitar la degradación del rendimiento. Realmente no puedo imaginar un caso en el que no sepas nada sobre el archivo con el que estás tratando, por lo que esto no debería ser un gran compromiso.

Toma el guión aquí . Gracias al autor anterior por liderar el camino.

escalada746
fuente
Realmente bien hecho para mantener este script. Funcionó muy bien la exportación de algún tiempo caducidad correcciones en miles de capas :)
iwasrobbed
7

EL CRÉDITO VA A JOHANNES POR CONTRIBUIR EL ARCHIVO. ¡MUCHAS GRACIAS!

He agregado una función que me ayudó a revisar mi archivo de capa 2448 en aproximadamente 3 horas.

Aquí está el enlace al archivo modificado Descargar aquí

Mike June Bug Captain
fuente
6

Actualicé el script para usar el BackgroundLayer principal del documento. Para que cada jpg que exporta se compile con él.

Sería genial si alguien agregara etiquetado a las capas para convertirlas en capas maestras en lugar de la capa de fondo predeterminada ;-)

guión 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
fuente