Skip to main content
Inspiring
November 24, 2024
Open for Voting

Saving JPEGs Via an Action

  • November 24, 2024
  • 23 replies
  • 1321 views

I have an action that saves JPEG files. Basically, it changes to 8-bit mode, does a Save A Copy, choose file type JPEG and Saves the file. The first issue is that in PS 26.1, the folder to save to is always the same folder as that used when the action was created. I believe previously in earlier PS versions, it always brought up the most recently saved folder. If I am working in a specific folder, adjust an image as desired, save a PSD file, and then subsequently click my action to Save As JPEG, the folder where JPEG will be saved is always the same, which is very annoying because have to navigate to the current folder. You can imaging if I have multiple images to edit, this is bothersome because it takes extra time. This could be a bug that did not occur in 26.0 or previous versions. Secondly, I've asked for this before, but please change the code to always save to the same folder where the saved PSD file is located. I don't want to navigate to a different folder ever when saving a JPEG file, in an action, after having opened or saved the image to a PSD file. Navigating is unnecessary if the code were revised to do as I requested.

23 replies

Inspiring
December 3, 2024

@Stephen Marsh 

 

This is a summary of all the preceding posts for reference. My goal was to use an action to save the currently active image as a JPEG. Recording an action that included clicking on the Save as Copy menu item recorded the then active folder at the time the action was recorded. However, sometime later, if I was working in a different folder, the JPEG save dialog required navigation from the folder in the recorded action to the new currently active folder. I had to do that navigation for every JPEG file I saved, and all of that navigation was very annoying and required far too much time.

 

This is what I wanted to do. If, for example, the original source path, filename and extension was F:\MyFamily\BrothersAndSisters.psd. I wanted to run the action and

 

a) sometimes save the image as F:\MyFamily\BrothersAndSisters.jpg
b) sometimes save the image as F:\MyFamily\Siblings.jpg
c) sometimes save the image as C:\Social Media\Brothers and Sisters.

 

Stephan Marsh helped me write javascript to solve the problem. Here is the Save As JPEG.jsx script we ended up using.

 

//  Save a JPEG with menu item Save a Copy initialized with the active path
//  parameter. It also gives the user a chance to change the saved path and 
//  file name if desired.
//  
//  Created with assistance from Stephen Marsh
//  
//  Also used ScriptListener plug-in downloaded from
//  https://helpx.adobe.com/photoshop/kb/downloadable-plugins-and-content.html
//  and a helpful video
//  https://www.youtube.com/watch?v=TlOa9temEus
//
//  Ken Curtis

#target photoshop

if (app.documents.length !== 0)
  {

  // Get active path
  var docPath = app.activeDocument.path;

  // Remove extensio from current active document
  var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');

  // Invoke menu item Save a Copy with desired parameters and execute it
  var desc259 = new ActionDescriptor();
  var desc260 = new ActionDescriptor();
  desc260.putInteger(charIDToTypeID("EQlt"), 9);
  desc260.putEnumerated(charIDToTypeID("MttC"), charIDToTypeID("MttC"), 
    charIDToTypeID("None"));
  desc259.putObject(charIDToTypeID("As  "), charIDToTypeID("JPEG"), desc260);
  desc259.putPath(charIDToTypeID("In  "), new File(docPath + '/' + docName));
  desc259.putBoolean(charIDToTypeID("Cpy "), true);
  desc259.putBoolean(charIDToTypeID("LwCs"), true);
  desc259.putInteger(charIDToTypeID("Dpth"), 8);
  executeAction(charIDToTypeID("save"), desc259, DialogModes.ALL);

  }

 else
  alert('You must have a file opened!');

 

This shows an image of the script used within the Save as JPEG action

 

 

The action changes the mode to 8 bits, saves the JPEG file and returns to the previous history state.

 

Ken

 

 

 

Inspiring
December 2, 2024

@Stephen Marsh 

 

Thanks, Stephan. I was not aware of the </> button. Next time I will use it.

 

I will edit my post to insert the code, just for accuracy, even though you cleaned it.

 

Ken

Stephen Marsh
Community Expert
Community Expert
December 2, 2024

@Ken Curtis 

 

That's great, welcome to scripting!

 

Use the forum software buttons </> to insert code so it doesn't become corrupted.

 

For example, your four-character charIDToTypeID codes have been truncated to 3 characters and the script fails (there should be 2 spaces after As):

 

var idAs = charIDToTypeID( "As " );

 

Should be:

 

var idAs = charIDToTypeID( "As  " );

 

ScriptingListener records some unnecessary info, so you can clean this up a little. It makes no difference to the script execution timing, it's just a little cleaner:

 

// Save a JPEG with menu item Save a Copy initialized with the active path
// parameter. It also gives the user a chance to change the saved path and
// file name if desired.
//
// Created with assistance from Stephen Marsh
//
// Also used ScriptListener plug-in downloaded from
// https://helpx.adobe.com/photoshop/kb/downloadable-plugins-and-content.html
#target photoshop
if (app.documents.length !== 0) {
    // Get active path
    var docPath = app.activeDocument.path;
    // Remove extensio from current active document
    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
    // Invoke menu item Save a Copy with desired parameters and execute it
    var desc259 = new ActionDescriptor();
    var desc260 = new ActionDescriptor();
    desc260.putInteger(charIDToTypeID("EQlt"), 9);
    desc260.putEnumerated(charIDToTypeID("MttC"), charIDToTypeID("MttC"), charIDToTypeID("None"));
    desc259.putObject(charIDToTypeID("As  "), charIDToTypeID("JPEG"), desc260);
    desc259.putPath(charIDToTypeID("In  "), new File(docPath + '/' + docName));
    desc259.putBoolean(charIDToTypeID("Cpy "), true);
    desc259.putBoolean(charIDToTypeID("LwCs"), true);
    desc259.putInteger(charIDToTypeID("Dpth"), 8);
    executeAction(charIDToTypeID("save"), desc259, DialogModes.ALL);
}
else {
    alert('You must have a file opened!');
}

 

P.S. Your code is essentially the same as the one that I asked you to try:

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/save-as-jpeg-again/td-p/12650865

 

 

Inspiring
December 2, 2024

@Stephen_A_Marsh 

 

I played around with your suggestions and was not able to get what I wanted, but thank you for trying. I finally was able to create a script and an action that does exactly what the original Save as Copy should have done when incorporating Save as Copy into an action. Below is the information that Photoshop users (and Adobe developers) can use.

 

Here is the javascript file: (Note: post edited to show code properly.)

 

//  Save a JPEG with menu item Save a Copy initialized with the active path
//  parameter. It also gives the user a chance to change the saved path and 
//  file name if desired.
//  
//  Created with assistance from Stephen Marsh
//  
//  Also used ScriptListener plug-in downloaded from
//  https://helpx.adobe.com/photoshop/kb/downloadable-plugins-and-content.html
//  and a helpful video
//  https://www.youtube.com/watch?v=TlOa9temEus
//
//  Ken Curtis

#target photoshop

if (app.documents.length !== 0)
  {

  // Get active path
  var docPath = app.activeDocument.path;

  // Remove extension from current active document
  var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');

  // Invoke menu item Save a Copy with desired parameters and execute it
  var idsave = charIDToTypeID( "save" );
  var desc259 = new ActionDescriptor();
  var idAs = charIDToTypeID( "As  " );
  var desc260 = new ActionDescriptor();
  var idEQlt = charIDToTypeID( "EQlt" );
  desc260.putInteger( idEQlt, 9 );
  var idMttC = charIDToTypeID( "MttC" );
  var idMttC = charIDToTypeID( "MttC" );
  var idNone = charIDToTypeID( "None" );
  desc260.putEnumerated( idMttC, idMttC, idNone );
  var idJPEG = charIDToTypeID( "JPEG" );
  desc259.putObject( idAs, idJPEG, desc260 );
  var idIn = charIDToTypeID( "In  " );
  desc259.putPath( idIn, new File(docPath + '/' + docName));
  var idDocI = charIDToTypeID( "DocI" );
  desc259.putInteger( idDocI, 59 );
  var idCpy = charIDToTypeID( "Cpy " );
  desc259.putBoolean( idCpy, true );
  var idLwCs = charIDToTypeID( "LwCs" );
  desc259.putBoolean( idLwCs, true );
  var idDpth = charIDToTypeID( "Dpth" );
  desc259.putInteger( idDpth, 8 );
  var idsaveStage = stringIDToTypeID( "saveStage" );
  var idsaveStageType = stringIDToTypeID( "saveStageType" );
  var idsaveBegin = stringIDToTypeID( "saveBegin" );
  desc259.putEnumerated( idsaveStage, idsaveStageType, idsaveBegin );
  executeAction( idsave, desc259, DialogModes.ALL );

  } 
else
  {
  alert('You must have a file opened!');
  }

 

Here is image of the script used within the Save as JPEG action

 

Comments invited.

Ken

 

 

Inspiring
December 2, 2024

@Stephen Marsh 

 

I played around with your suggestions and was not able to get what I wanted, but thank you for trying. I finally was able to create a script and an action that does exactly what the original Save as Copy should have done when incorporating Save as Copy into an action. Below is the information that Photoshop users (and Adobe developers) can use.

 

Here is the javascript file:

Ooops, file copied incorectly. Will replace in a little bit.

 

 

Stephen Marsh
Community Expert
Community Expert
December 1, 2024

@Ken Curtis 

 

You previously only mentioned the requirement to change the name, not the file path, so that's what I revised.

 

If you want the ability to change name and path, as previously mentioned, just record an action and enable the modal control on the action step to make it interactive.

 

Or, you can take a look at the scripts in the linked topics before I revised the code and let me know if they work for you.

 

 


@Ken Curtis wrote:

In reading your script, there is no means for specifying a new path.


 

You could try this:

 

/*
JPEG Save As a Copy to Source Directory Using Custom Filename and Path.jsx
Stephen Marsh
v1.0 - 2nd December 2024
https://community.adobe.com/t5/photoshop-ecosystem-ideas/saving-jpegs-via-an-action/idc-p/15002989
*/

#target photoshop

if (app.documents.length !== 0) {

    // Check if the bit depth is 32 bpc
    if (app.activeDocument.bitsPerChannel == BitsPerChannelType.THIRTYTWO) {
        throw alert("Script cancelled!\rThe image mode is 32 bpc, tone mapping to 8 or 16 bpc is required before continuing.");
    }

    // Remove extension
    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
    var docNameInput = prompt('Enter a filename (without extension):', docName);

    // Remove extension
    var docNameOutput = docNameInput.replace(/\.[^\.]+$/, '');

    // Set the output folder
    var docPath = Folder.selectDialog("Select the output folder:");

    // File Path & Naming
    var saveFileJPEG = new File(docPath + '/' + docNameOutput + '.jpg');

    if (saveFileJPEG.exists) {
        // true = 'No' as default active button
        if (!confirm("File exists, overwrite: Yes or No?", true))
            // throw alert("Script cancelled!");
            throw null;
    }

    jpegOptions(saveFileJPEG);

    // JPEG Options
    function jpegOptions(saveFileJPEG) {
        jpgSaveOptions = new JPEGSaveOptions();
        jpgSaveOptions.embedColorProfile = true;
        jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
        jpgSaveOptions.matte = MatteType.NONE;
        jpgSaveOptions.quality = 10;
        // Save a Copy
        activeDocument.saveAs(saveFileJPEG, jpgSaveOptions, true, Extension.LOWERCASE);
    }

    app.beep();
    // alert('JPEG saved!');

} else {
    alert('You must have a document open!');
}

 

 

Inspiring
December 1, 2024

@Stephen Marsh

 

Thank you very much, we are getting closer. I really appreciate your effort.

 

The problem with the revised code is the image is always saved to the source folder. I want that most of the time, but there are times when I not only want to rename the JPEG's filename but also save it in a different folder.

 

For example: The original source path, filename and extension is F:\MyFamily\BrothersAndSisters.psd. I want to run the action and
a) sometimes save the image as F:\MyFamily\BrothersAndSisters.jpg
b) sometimes save the image as F:\MyFamily\Siblings.jpg
c) sometimes save the image as C:\Social Media\Brothers and Sisters.

 

In reading your script, there is no means for specifying a new path. I would be happy to have the Adobe/Windows Save As Copy dialog appear where I can accept source path and filename as is but also have an opportunity to change the filename and/or navigate to a different folder.

 

Ken

Stephen Marsh
Community Expert
Community Expert
December 1, 2024

@Ken Curtis 

 

As requested, this version will prompt for a custom name:

 

/*
JPEG Save As a Copy to Source Directory Using Custom Filename.jsx
Stephen Marsh
v1.0 - 26th November 2024
https://community.adobe.com/t5/photoshop-ecosystem-ideas/saving-jpegs-via-an-action/idc-p/15002989
*/

#target photoshop

if (app.documents.length !== 0) {

    // Check if the bit depth is 32 bpc
    if (app.activeDocument.bitsPerChannel == BitsPerChannelType.THIRTYTWO) {
        throw alert("Script cancelled!\rThe image mode is 32 bpc, tone mapping to 8 or 16 bpc is required before continuing.");
    }

    try {
        // Use the previously saved path
        var docPath = app.activeDocument.path;
    } catch (e) {
        // If unsaved, prompt for save directory
        var docPath = new Folder.selectDialog("Unsaved base file, select the output folder:");
    }

    // Remove extension
    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
    var docNameInput = prompt('Enter a filename (without extension):', docName);

    // Remove extension
    var docNameOutput = docNameInput.replace(/\.[^\.]+$/, '');

    // File Path & Naming
    var saveFileJPEG = new File(docPath + '/' + docNameOutput + '.jpg');

    if (saveFileJPEG.exists) {
        // true = 'No' as default active button
        if (!confirm("File exists, overwrite: Yes or No?", true))
            // throw alert("Script cancelled!");
            throw null;
    }

    jpegOptions(saveFileJPEG);

    // JPEG Options
    function jpegOptions(saveFileJPEG) {
        jpgSaveOptions = new JPEGSaveOptions();
        jpgSaveOptions.embedColorProfile = true;
        jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
        jpgSaveOptions.matte = MatteType.NONE;
        jpgSaveOptions.quality = 10;
        // Save a Copy
        activeDocument.saveAs(saveFileJPEG, jpgSaveOptions, true, Extension.LOWERCASE);
    }

    app.beep();
    // alert('JPEG saved!');

} else {
    alert('You must have a document open!');
}
Stephen Marsh
Community Expert
Community Expert
November 28, 2024

@Ken Curtis 

 

The code was designed for "headless" operation, although it can be modified, perhaps one of these scripts that I previously wrote may be a good starting point for interactivity:

 

Inspiring
November 27, 2024

Stephen_A_Marsh I added your script to Photoshop and created a new action to Save As JPEG using your script.

 

Your script worked very well, and I am a much happier camper.

I wonder if you would take a second look and revise the code. My reason is because there are occasionally times when I want save the JPEG file with a different file name. Example: I have a .PSD file with the name BoatInWater.psd. I want to save the original color file as a JPEG into BoatInWater.jpg. After doing that, I may, as an example, want to add a black and white adjustment layer to the image. Rather than overwriting the BoatInWater.jpg file, I want to save the file as BoatInWater_B&W.jpg. Is there a way to modify your code to give me an opportunity to change the file name? Maybe the folder too.

I appreciate what you have done so far. It is definitely a help and saves a lot of navigating (and extra keystrokes and mouse clicks) when I do want to save the image as a JPEG with the original base file name.