Export Layers to file individually

Hey there!

I’m developing my first plugin with UXP and I would like to know if it’s possible to export each layer to a separate file, something like the createRenditions in Adobe UXD?

If it’s not possible, this will be in the photoshop uxp plugin roadmap?

Thanks in advance!

Hi there!

Welcome to the forum.

You can definitely go to File --> Export --> Layers to Files through the Photoshop menu. But is that reachable via UXP?

If it isn’t, you could try using the Alchemist plugin to “listen” for the event. Check out @DavideBarranca’s video here: https://www.youtube.com/watch?v=aZn_6X6nvUM - that particular video has some listening and layer commands you may find useful (and all the videos in that series are very helpful!)

2 Likes

Thanks so much!

After other topic I created, I was trying this listener and layers export in other way and weren’t working, buuuut this way File --> Export --> Layers worked like a charm!

Again, thanks so much :))

Hello again!

This generated a code and rendered all layers as well, but the code that Alchemist gave to me when I try to execute I hae the following error:


The code tha Alchesmit gave to me is:

const batchPlay = require("photoshop").action.batchPlay;

const result = await batchPlay(
[
   {
      "_obj": "6f1c2cf5-4a97-4e32-8f59-f5d7a087adef",
      "message": "Configurações da ação Exportar Camadas para Arquivos",
      "destination": "Z:\\destination\\path\\layers",
      "fileNamePrefix": "layer:",
      "visibleOnly": true,
      "fileType": 7,
      "icc": true,
      "jpegQuality": "8",
      "psdMaxComp": true,
      "tiffCompression": "TIFFEncoding.NONE",
      "tiffJpegQuality": "8",
      "pdfEncoding": "PDFEncoding.JPEG",
      "pdfJpegQuality": "8",
      "targaDepth": "TargaBitsPerPixels.TWENTYFOUR",
      "bmpDepth": "BMPDepthType.TWENTYFOUR",
      "png24Transparency": true,
      "png24Interlaced": false,
      "png24Trim": true,
      "png8Transparency": true,
      "png8Interlaced": false,
      "png8Trim": true,
      "_isCommand": true,
      "_options": {
         "dialogOptions": "dontDisplay"
      }
   }
],{
   "synchronousExecution": false,
   "modalBehavior": "fail"
});

I noticed that the alert error was in Portuguese, the translated message would be:

Error 54: Javascript Exception not caught: Error: Unsupported type in descriptorToObject DescValueType.INTEGERTYPE, line:2455
-> throw (new Error("Unsupported type in descriptorToObject" + t) );

Do you know what could it be? :frowning:

Perhaps fileType 7 is the wrong number? :thinking:
Maybe @Jarda can help…

1 Like

No, I don’t think so.

I tried to export to other file types like PDF, JPEG, PNG (their file types number are different) and the error message is the same :confused:

Perhaps it’s more of a @Barkin question…

It could be possibly caused by file path since in UXP you need tokens instead and I am not sure if that JSX script accepts it as a path or string data type.

Or maybe you do use strings instead of numbers.

I think it’s about this way, because changing the file type argument to String the error changed and it is:

Error: Unsupported type in descriptorToObject DescValueType.OBJECTTYPE

Or enums could be a problem. Since enum is in fact number but you pass it as string. So I am not sure how this is translated on the other side.

I’m little lost, I tried a lot of different things here.
Do you have any idea of what I could do?

Definitely fix the File path – it’ll cause problems regardless of the rest of it.

See https://www.adobe.io/photoshop/uxp/uxp/reference-js/Modules/uxp/Persistent%20File%20Storage/FileSystemProvider/#createsessiontokenentry for an example.

@kerrishotts that is not sure. Because this UXP batchPlay calls ExtendScript. It can pass the path as a string and on the other side, it will convert the string type into a file path type and use it in its own executeAction() …it would be a nice hack :smiley:

So, Fixing the file path does not change the error message, I tried the following:

const fs = require('uxp').storage.localFileSystem;
let entry = await fs.getFolder();
let token = fs.createSessionToken(entry);

And then changed the filePath to use this token, but the error message is the same. @Jarda said something about the fileType and I think may be it, because the error message changed when I tried to use a string instead of an integer (but I don’t know, just hunches).

1 Like

@guircasimiro Did you ever manage to fix this issue?

Did this ever get solved? I’ve been reticent to ask in my own thread, as this exact question was already asked right here. I still have not figured this out, so I’ve been entirely relying on Adobe’s built-in “generate image assets” feature, which involves lots of regex to follow their formatted layer naming/exporting convention via https://helpx.adobe.com/photoshop/using/generate-assets-layers.html

If explaining the process is too arcane, are there any example UXP scripts that I can look at, which have this functionality built-in? I can just extract code from there.

I would greatly prefer to not have to rely on “generate image assets”. All I’d like to do is understand how to export a layer (or layer group) as a .png.

A blunt way of doing it would be to duplicate each layer into a new document and then save that in whatever format required.

Are there any example scripts that demonstrate how an image is exported from a .psd file to the hard drive?

I’ve attempted to record via batchPlay, but Alchemist captures none of my exports as recordable events. I’ve searched the UXP documentation for anything regarding “export” but I’ve found nothing, so far.

I use select and export in batch play

import { action, core, app} from 'photoshop';
import { Layer} from 'photoshop/dom/Layer';
//
export const exportLayerAsPng = async (layer:Layer, path:string, imageSuffix:string): Promise<void> => {
  const { id, name } = layer;
  console.log("exportLayerAsPng",imageSuffix, name);
  console.log("", path)
  const selectCommand = 	  {
    _obj: 'select',
    _target: [
      {
      _ref: 'layer',
       _id: id,
      },
    ],
    makeVisible: false,
    layerID: [id],
    _isCommand: false,
  }
  //  
  const exportCommand = {
    _obj: 'exportSelectionAsFileTypePressed',
    _target: { _ref: 'layer', _enum: 'ordinal', _value: 'targetEnum' },
    fileType: 'png',
    quality: 32,
    metadata: 0,
    destFolder: path, //destFolder.nativePath,
    sRGB: true,
    openWindow: false,
    _options: { dialogOptions: 'dontDisplay' },
  };
  //
  await core.executeAsModal(
    async () => {
        await action.batchPlay([selectCommand,  exportCommand], { modalBehavior: 'execute', synchronousExecution:false });
    },
    { commandName: `Export ${layer.name} Layer As PNG start` }
  );
};
3 Likes