Export JPEG and get file size in UXP

Is there any further information on this? Is there any way to export a file using UXP? I can confirm that the Alchemist plugin, even the development version I installed via the UXP Developer Tool, returns zero events for any file export.

This seems like it should be utterly basic functionality.

2 Likes

I ended up using legacy export, which can be recorded by actions/Alchemist

I remember seeing export in the road map under (far future) more than a year ago I think

I also read somewhere in the forums that export functionality is available to be used under the hood, I just didn’t manage to figure out the parameters since it’s private and undocumented

TLDR: not available yet
you can record legacy export
you can use quick export which only allows choosing the target folder but not the filename

Can the ā€œexportā€ you are talking about be substituted with ā€œsaveAsā€?

Here’s an example

Document about saveAs

Document about save options

It cannot, because I need to be able to downscale on exporting. I do wish that I could use it, though!

@Maher Thanks so much for this suggestion! This looks very promising, though, I must admit, this is one of the more confusing event descriptors I’ve come across. Would you happen to have any further information on what the legacy export parameters mean?

property names are a mess, for my case I used known value in the properties I want to be dynamic and looked for that value and replaced it with my own variables.

async function quickExport(folder, filename, quality) {
   await executeAsModal(async () => {
      let command = { "_obj": "export", "using": { "$DIDr": true, "$EICC": false, "$Mtt": false, "$MttB": 255, "$MttG": 255, "$MttR": 255, "$Op": { "_enum": "$SWOp", "_value": "$OpSa" }, "$Pass": 1, "$QCUI": 0, "$QChS": 0, "$QChT": false, "$QChV": false, "$SHTM": false, "$SImg": true, "$SWch": { "_enum": "$STch", "_value": "$CHsR" }, "$SWmd": { "_enum": "$STmd", "_value": "$MDCC" }, "$SWsl": { "_enum": "$STsl", "_value": "$SLAl" }, "$obCS": { "_enum": "$STcs", "_value": "$CS01" }, "$obIA": false, "$obIP": "", "$ohAA": true, "$ohAC": { "_enum": "$SToc", "_value": "$OC03" }, "$ohCA": false, "$ohEn": { "_enum": "$STen", "_value": "$EN00" }, "$ohIC": true, "$ohIZ": true, "$ohIn": -1, "$ohLE": { "_enum": "$STle", "_value": "$LE03" }, "$ohQA": true, "$ohTC": { "_enum": "$SToc", "_value": "$OC03" }, "$ohXH": false, "$olCS": false, "$olEC": { "_enum": "$STst", "_value": "$ST00" }, "$olNC": [{ "$ncTp": { "_enum": "$STnc", "_value": "$NC00" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC19" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC28" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC24" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC24" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC24" }, "_obj": "$SCnc" }], "$olSH": { "_enum": "$STsp", "_value": "$SP04" }, "$olSV": { "_enum": "$STsp", "_value": "$SP04" }, "$olWH": { "_enum": "$STwh", "_value": "$WH01" }, "$ovCB": true, "$ovCM": false, "$ovCU": true, "$ovCW": true, "$ovFN": filename, "$ovNC": [{ "$ncTp": { "_enum": "$STnc", "_value": "$NC01" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC20" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC02" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC19" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC06" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC24" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC24" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC24" }, "_obj": "$SCnc" }, { "$ncTp": { "_enum": "$STnc", "_value": "$NC22" }, "_obj": "$SCnc" }], "$ovSF": true, "$ovSN": "images", "_obj": "SaveForWeb", "blur": 0.0, "format": { "_enum": "$IRFm", "_value": "JPEG" }, "in": { "_kind": "local", "_path": folder }, "interfaceIconFrameDimmed": false, "optimized": true, "quality": quality } };
      result = await batchPlay([command], {});
   }, { "commandName": "Exporting..." });
}

the example above exports JPG using a token, filename and quality

Oh, very interesting! I’m wondering: when I looked at this command on alchemist, I saw no option for ā€œquality,ā€ so I do not know what that property is supposed to expect. [EDIT] I’m guessing that, since my own goals are to save as PNG24, there is no quality setting that I’d be making.

When I recorded this action with Alchemist and changed the quality setting, I still could not get ā€œqualityā€ to appear. What do I put for quality? In my case, I want to export to a target resolution, so I’m assuming that I need to change _value for:

      "$HScl": {
         "_unit": "percentUnit",
         "_value": 50
      },
      "$VScl": {
         "_unit": "percentUnit",
         "_value": 50
      },

Additionally, just to be sure, in your field, you have a folder option. Is this the usual method for retrieving a folder for export? [EDIT] the code below is incorrect. See at end of post.

async function getUserFolderSessionToken() {
  const entry = await fs.getFolder();
  try {
    return entry;
  } catch (e) {
    console.error(e);
  }
};

edit I did some more investigation, and I applied the above steps. However, I am getting the following error:

NAPI API failure: String expected

What I did slightly differently was have a separate function for populating the event descriptor, then I assigned that to [batchCommands], then I inserted that into:

async function exportLegacy(folder, fileName, scalePercent) {
  let batchCommands = [eventExportLegacy(folder, fileName, scalePercent)];
  try {
    return await executeAsModal(async () => {
      /*I get the error here*/await batchPlay(batchCommands, {});
    }, { commandName: "Legacy Export" });
  } catch (e) {
    console.error(e);
  }
};

[EDIT]
This is the code I used for retrieving a session token to feed into the batchplay event descriptor:

async function getUserFolderSessionToken() {
  let entry = await fs.getFolder();
  let token = fs.createSessionToken(entry);
  console.log(token);
  try {
    return token;
  } catch (e) {
    console.error(e);
  }
};

I was missing a step. fs.GetFolder(); does not retrieve the values needed for writing to a folder. I need that second line let token = fs.createSessionToken(entry); to effectively act as the ā€œfolder path to write stuff toā€ explained here.

1 Like