2

I've searched existing questions for this, but I'm not finding a way to do this one specific task.

I work from 24mp photographs, fixing up across several apps but always ending in Photoshop.
I have already tagged my file by the original _DSC number plus a 'scene name' & will file back into the day's shooting folder. That part is fine.

Once completed & whilst the original Ps is still open, as a last 'filing task' I then need to generate two jpgs, back into the original folder, converted to sRGB, containing all exif data, in two different sizes & at two different qualities, each suffixed with the 'size' like the new Save for Web can do eg [email protected]

So,
[email protected] [at 100% quality]
[email protected] [at 70% quality]

These requirements mean I cannot use the new 'Export As' [because it discards exif] or a simple Save As.. [no resize] so it seems I must use the old 'Save for Web'.

I've tried setting this up as an Action, but that hard-codes the naming & destination. It also fills the Action parameter list with so much extraneous data that I can barely follow it. I'm by no means an 'actions expert'.
Toggling the action to show the dialog basically negates the entire point of having set it as an action & I can't figure out a way to just edit those couple of parameters inside the 'Export' part of the two saves.

Is there any way to edit an action to change the hard-coded names & destinations to instead use suffixes & save back to original location?

Or is there an alternative method to achieve this?

I'm on Mac Mojave & current Ps 2020, if relevant.

2 Answers 2

2

There's a plugin for Photoshop called ScriptingListener: after it's installed, it starts to write a log of most of the actions you do in Photoshop as code (basically everything you can save as an Action can be written as code). The code (Javascript) it gives you is quite difficult to read and can be confusing but! This allows you to put much more different conditions. It's like Actions 2.0.

Here's an example of code generated from running Save For Web command. I save a file as JPG with 33% scale and 92 quality:

// =======================================================
var idExpr = charIDToTypeID( "Expr" );
    var desc21 = new ActionDescriptor();
    var idUsng = charIDToTypeID( "Usng" );
        var desc22 = new ActionDescriptor();
        var idOp = charIDToTypeID( "Op  " );
        var idSWOp = charIDToTypeID( "SWOp" );
        var idOpSa = charIDToTypeID( "OpSa" );
        desc22.putEnumerated( idOp, idSWOp, idOpSa );
        var idDIDr = charIDToTypeID( "DIDr" );
        desc22.putBoolean( idDIDr, true );
        var idIn = charIDToTypeID( "In  " );
        desc22.putPath( idIn, new File( "E:\\temp\\del" ) );
        var idovFN = charIDToTypeID( "ovFN" );
        desc22.putString( idovFN, """Untitled-3-033.jpg""" );
        var idFmt = charIDToTypeID( "Fmt " );
        var idIRFm = charIDToTypeID( "IRFm" );
        var idJPEG = charIDToTypeID( "JPEG" );
        desc22.putEnumerated( idFmt, idIRFm, idJPEG );
        var idIntr = charIDToTypeID( "Intr" );
        desc22.putBoolean( idIntr, false );
        var idQlty = charIDToTypeID( "Qlty" );
        desc22.putInteger( idQlty, 92 );
        var idQChS = charIDToTypeID( "QChS" );
        desc22.putInteger( idQChS, 0 );
        var idQCUI = charIDToTypeID( "QCUI" );
        desc22.putInteger( idQCUI, 0 );
        var idQChT = charIDToTypeID( "QChT" );
        desc22.putBoolean( idQChT, false );
        var idQChV = charIDToTypeID( "QChV" );
        desc22.putBoolean( idQChV, false );
        var idOptm = charIDToTypeID( "Optm" );
        desc22.putBoolean( idOptm, true );
        var idPass = charIDToTypeID( "Pass" );
        desc22.putInteger( idPass, 1 );
        var idblur = charIDToTypeID( "blur" );
        desc22.putDouble( idblur, 0.000000 );
        var idMtt = charIDToTypeID( "Mtt " );
        desc22.putBoolean( idMtt, false );
        var idEICC = charIDToTypeID( "EICC" );
        desc22.putBoolean( idEICC, false );
        var idMttR = charIDToTypeID( "MttR" );
        desc22.putInteger( idMttR, 255 );
        var idMttG = charIDToTypeID( "MttG" );
        desc22.putInteger( idMttG, 255 );
        var idMttB = charIDToTypeID( "MttB" );
        desc22.putInteger( idMttB, 255 );
        var idHScl = charIDToTypeID( "HScl" );
        var idPrc = charIDToTypeID( "#Prc" );
        desc22.putUnitDouble( idHScl, idPrc, 33.333333 );
        var idVScl = charIDToTypeID( "VScl" );
        var idPrc = charIDToTypeID( "#Prc" );
        desc22.putUnitDouble( idVScl, idPrc, 33.333333 );
        var idSHTM = charIDToTypeID( "SHTM" );
        desc22.putBoolean( idSHTM, false );
        var idSImg = charIDToTypeID( "SImg" );
        desc22.putBoolean( idSImg, true );
        var idSWsl = charIDToTypeID( "SWsl" );
        var idSTsl = charIDToTypeID( "STsl" );
        var idSLAl = charIDToTypeID( "SLAl" );
        desc22.putEnumerated( idSWsl, idSTsl, idSLAl );
        var idSWch = charIDToTypeID( "SWch" );
        var idSTch = charIDToTypeID( "STch" );
        var idCHsR = charIDToTypeID( "CHsR" );
        desc22.putEnumerated( idSWch, idSTch, idCHsR );
        var idSWmd = charIDToTypeID( "SWmd" );
        var idSTmd = charIDToTypeID( "STmd" );
        var idMDCC = charIDToTypeID( "MDCC" );
        desc22.putEnumerated( idSWmd, idSTmd, idMDCC );
        var idohXH = charIDToTypeID( "ohXH" );
        desc22.putBoolean( idohXH, false );
        var idohIC = charIDToTypeID( "ohIC" );
        desc22.putBoolean( idohIC, true );
        var idohAA = charIDToTypeID( "ohAA" );
        desc22.putBoolean( idohAA, true );
        var idohQA = charIDToTypeID( "ohQA" );
        desc22.putBoolean( idohQA, true );
        var idohCA = charIDToTypeID( "ohCA" );
        desc22.putBoolean( idohCA, false );
        var idohIZ = charIDToTypeID( "ohIZ" );
        desc22.putBoolean( idohIZ, true );
        var idohTC = charIDToTypeID( "ohTC" );
        var idSToc = charIDToTypeID( "SToc" );
        var idOCzerothree = charIDToTypeID( "OC03" );
        desc22.putEnumerated( idohTC, idSToc, idOCzerothree );
        var idohAC = charIDToTypeID( "ohAC" );
        var idSToc = charIDToTypeID( "SToc" );
        var idOCzerothree = charIDToTypeID( "OC03" );
        desc22.putEnumerated( idohAC, idSToc, idOCzerothree );
        var idohIn = charIDToTypeID( "ohIn" );
        desc22.putInteger( idohIn, -1 );
        var idohLE = charIDToTypeID( "ohLE" );
        var idSTle = charIDToTypeID( "STle" );
        var idLEzerothree = charIDToTypeID( "LE03" );
        desc22.putEnumerated( idohLE, idSTle, idLEzerothree );
        var idohEn = charIDToTypeID( "ohEn" );
        var idSTen = charIDToTypeID( "STen" );
        var idENzerozero = charIDToTypeID( "EN00" );
        desc22.putEnumerated( idohEn, idSTen, idENzerozero );
        var idolCS = charIDToTypeID( "olCS" );
        desc22.putBoolean( idolCS, false );
        var idolEC = charIDToTypeID( "olEC" );
        var idSTst = charIDToTypeID( "STst" );
        var idSTzerozero = charIDToTypeID( "ST00" );
        desc22.putEnumerated( idolEC, idSTst, idSTzerozero );
        var idolWH = charIDToTypeID( "olWH" );
        var idSTwh = charIDToTypeID( "STwh" );
        var idWHzeroone = charIDToTypeID( "WH01" );
        desc22.putEnumerated( idolWH, idSTwh, idWHzeroone );
        var idolSV = charIDToTypeID( "olSV" );
        var idSTsp = charIDToTypeID( "STsp" );
        var idSPzerofour = charIDToTypeID( "SP04" );
        desc22.putEnumerated( idolSV, idSTsp, idSPzerofour );
        var idolSH = charIDToTypeID( "olSH" );
        var idSTsp = charIDToTypeID( "STsp" );
        var idSPzerofour = charIDToTypeID( "SP04" );
        desc22.putEnumerated( idolSH, idSTsp, idSPzerofour );
        var idolNC = charIDToTypeID( "olNC" );
            var list3 = new ActionList();
                var desc23 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCzerozero = charIDToTypeID( "NC00" );
                desc23.putEnumerated( idncTp, idSTnc, idNCzerozero );
            var idSCnc = charIDToTypeID( "SCnc" );
            list3.putObject( idSCnc, desc23 );
                var desc24 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNConenine = charIDToTypeID( "NC19" );
                desc24.putEnumerated( idncTp, idSTnc, idNConenine );
            var idSCnc = charIDToTypeID( "SCnc" );
            list3.putObject( idSCnc, desc24 );
                var desc25 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwoeight = charIDToTypeID( "NC28" );
                desc25.putEnumerated( idncTp, idSTnc, idNCtwoeight );
            var idSCnc = charIDToTypeID( "SCnc" );
            list3.putObject( idSCnc, desc25 );
                var desc26 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwofour = charIDToTypeID( "NC24" );
                desc26.putEnumerated( idncTp, idSTnc, idNCtwofour );
            var idSCnc = charIDToTypeID( "SCnc" );
            list3.putObject( idSCnc, desc26 );
                var desc27 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwofour = charIDToTypeID( "NC24" );
                desc27.putEnumerated( idncTp, idSTnc, idNCtwofour );
            var idSCnc = charIDToTypeID( "SCnc" );
            list3.putObject( idSCnc, desc27 );
                var desc28 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwofour = charIDToTypeID( "NC24" );
                desc28.putEnumerated( idncTp, idSTnc, idNCtwofour );
            var idSCnc = charIDToTypeID( "SCnc" );
            list3.putObject( idSCnc, desc28 );
        desc22.putList( idolNC, list3 );
        var idobIA = charIDToTypeID( "obIA" );
        desc22.putBoolean( idobIA, false );
        var idobIP = charIDToTypeID( "obIP" );
        desc22.putString( idobIP, """""" );
        var idobCS = charIDToTypeID( "obCS" );
        var idSTcs = charIDToTypeID( "STcs" );
        var idCSzeroone = charIDToTypeID( "CS01" );
        desc22.putEnumerated( idobCS, idSTcs, idCSzeroone );
        var idovNC = charIDToTypeID( "ovNC" );
            var list4 = new ActionList();
                var desc29 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCzeroone = charIDToTypeID( "NC01" );
                desc29.putEnumerated( idncTp, idSTnc, idNCzeroone );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc29 );
                var desc30 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwozero = charIDToTypeID( "NC20" );
                desc30.putEnumerated( idncTp, idSTnc, idNCtwozero );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc30 );
                var desc31 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCzerotwo = charIDToTypeID( "NC02" );
                desc31.putEnumerated( idncTp, idSTnc, idNCzerotwo );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc31 );
                var desc32 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNConenine = charIDToTypeID( "NC19" );
                desc32.putEnumerated( idncTp, idSTnc, idNConenine );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc32 );
                var desc33 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCzerosix = charIDToTypeID( "NC06" );
                desc33.putEnumerated( idncTp, idSTnc, idNCzerosix );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc33 );
                var desc34 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwofour = charIDToTypeID( "NC24" );
                desc34.putEnumerated( idncTp, idSTnc, idNCtwofour );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc34 );
                var desc35 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwofour = charIDToTypeID( "NC24" );
                desc35.putEnumerated( idncTp, idSTnc, idNCtwofour );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc35 );
                var desc36 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwofour = charIDToTypeID( "NC24" );
                desc36.putEnumerated( idncTp, idSTnc, idNCtwofour );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc36 );
                var desc37 = new ActionDescriptor();
                var idncTp = charIDToTypeID( "ncTp" );
                var idSTnc = charIDToTypeID( "STnc" );
                var idNCtwotwo = charIDToTypeID( "NC22" );
                desc37.putEnumerated( idncTp, idSTnc, idNCtwotwo );
            var idSCnc = charIDToTypeID( "SCnc" );
            list4.putObject( idSCnc, desc37 );
        desc22.putList( idovNC, list4 );
        var idovCM = charIDToTypeID( "ovCM" );
        desc22.putBoolean( idovCM, false );
        var idovCW = charIDToTypeID( "ovCW" );
        desc22.putBoolean( idovCW, true );
        var idovCU = charIDToTypeID( "ovCU" );
        desc22.putBoolean( idovCU, true );
        var idovSF = charIDToTypeID( "ovSF" );
        desc22.putBoolean( idovSF, true );
        var idovCB = charIDToTypeID( "ovCB" );
        desc22.putBoolean( idovCB, true );
        var idovSN = charIDToTypeID( "ovSN" );
        desc22.putString( idovSN, """images""" );
    var idSaveForWeb = stringIDToTypeID( "SaveForWeb" );
    desc21.putObject( idUsng, idSaveForWeb, desc22 );
executeAction( idExpr, desc21, DialogModes.NO );

It's huge and terrifying, however it's easy to identify several lines that I'd want to change to get different results. There's a line with file path, file name, quality (desc22.putInteger( idQlty, 92 );), and scale (desc22.putUnitDouble( idHScl, idPrc, 33.333333 ); for horizontal and another similar for vertical scale).

So basically what we need is to be able to use this huge command with a name we want and a scale we want. And we don't want to repeat these chunks of code for each export. Also if it could look at least a little more pretty it'd be amazing.

Ok, so

  • to get active document name and path we can use activeDocument.name and activeDocument.path;
  • to reuse the code we can use functions and we can pass argumens to these functions;
  • to make the code a bit more readable amazing xbytorx made a a script ScriptListener Code Cleaner that's a part of his xtools library;

here's the final version of the script:

var filePath = activeDocument.path; // this can be changed to something like "/E/MyPhotos/JPEGs";
var fileName = activeDocument.name.replace(/\.[^.]+$/g, ""); // activeDocument.name will give a name with its extension, I want only a name

saveForWeb(fileName + "[email protected]", filePath, 90, 100); // I'm running my saveForWeb function and give it some arguments: a name I want, a path, quality and scale
saveForWeb(fileName + "[email protected]", filePath, 90, 33);

function saveForWeb(fileName, filePath, quality, scale)
{
  function cTID(s)
  {
    return app.charIDToTypeID(s);
  };

  function sTID(s)
  {
    return app.stringIDToTypeID(s);
  };

  var desc21 = new ActionDescriptor();
  var desc22 = new ActionDescriptor();
  desc22.putEnumerated(cTID('Op  '), cTID('SWOp'), cTID('OpSa'));
  desc22.putBoolean(cTID('DIDr'), true);
  desc22.putPath(cTID('In  '), new File(filePath)); // file path
  desc22.putString(cTID('ovFN'), fileName); // file name
  desc22.putEnumerated(cTID('Fmt '), cTID('IRFm'), cTID('JPEG'));
  desc22.putBoolean(cTID('Intr'), false);
  desc22.putInteger(cTID('Qlty'), quality); // quality
  desc22.putInteger(cTID('QChS'), 0);
  desc22.putInteger(cTID('QCUI'), 0);
  desc22.putBoolean(cTID('QChT'), false);
  desc22.putBoolean(cTID('QChV'), false);
  desc22.putBoolean(cTID('Optm'), true);
  desc22.putInteger(cTID('Pass'), 1);
  desc22.putDouble(cTID('blur'), 0.000000);
  desc22.putBoolean(cTID('Mtt '), false);
  desc22.putBoolean(cTID('EICC'), false);
  desc22.putInteger(cTID('MttR'), 255);
  desc22.putInteger(cTID('MttG'), 255);
  desc22.putInteger(cTID('MttB'), 255);
  desc22.putUnitDouble(cTID('HScl'), cTID('#Prc'), scale); // scale
  desc22.putUnitDouble(cTID('VScl'), cTID('#Prc'), scale); // scale
  desc22.putBoolean(cTID('SHTM'), false);
  desc22.putBoolean(cTID('SImg'), true);
  desc22.putEnumerated(cTID('SWsl'), cTID('STsl'), cTID('SLAl'));
  desc22.putEnumerated(cTID('SWch'), cTID('STch'), cTID('CHsR'));
  desc22.putEnumerated(cTID('SWmd'), cTID('STmd'), cTID('MDCC'));
  desc22.putBoolean(cTID('ohXH'), false);
  desc22.putBoolean(cTID('ohIC'), true);
  desc22.putBoolean(cTID('ohAA'), true);
  desc22.putBoolean(cTID('ohQA'), true);
  desc22.putBoolean(cTID('ohCA'), false);
  desc22.putBoolean(cTID('ohIZ'), true);
  desc22.putEnumerated(cTID('ohTC'), cTID('SToc'), cTID('OC03'));
  desc22.putEnumerated(cTID('ohAC'), cTID('SToc'), cTID('OC03'));
  desc22.putInteger(cTID('ohIn'), -1);
  desc22.putEnumerated(cTID('ohLE'), cTID('STle'), cTID('LE03'));
  desc22.putEnumerated(cTID('ohEn'), cTID('STen'), cTID('EN00'));
  desc22.putBoolean(cTID('olCS'), false);
  desc22.putEnumerated(cTID('olEC'), cTID('STst'), cTID('ST00'));
  desc22.putEnumerated(cTID('olWH'), cTID('STwh'), cTID('WH01'));
  desc22.putEnumerated(cTID('olSV'), cTID('STsp'), cTID('SP04'));
  desc22.putEnumerated(cTID('olSH'), cTID('STsp'), cTID('SP04'));
  var list3 = new ActionList();
  var desc23 = new ActionDescriptor();
  desc23.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC00'));
  list3.putObject(cTID('SCnc'), desc23);
  var desc24 = new ActionDescriptor();
  desc24.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC19'));
  list3.putObject(cTID('SCnc'), desc24);
  var desc25 = new ActionDescriptor();
  desc25.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC28'));
  list3.putObject(cTID('SCnc'), desc25);
  var desc26 = new ActionDescriptor();
  desc26.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC24'));
  list3.putObject(cTID('SCnc'), desc26);
  var desc27 = new ActionDescriptor();
  desc27.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC24'));
  list3.putObject(cTID('SCnc'), desc27);
  var desc28 = new ActionDescriptor();
  desc28.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC24'));
  list3.putObject(cTID('SCnc'), desc28);
  desc22.putList(cTID('olNC'), list3);
  desc22.putBoolean(cTID('obIA'), false);
  desc22.putString(cTID('obIP'), "");
  desc22.putEnumerated(cTID('obCS'), cTID('STcs'), cTID('CS01'));
  var list4 = new ActionList();
  var desc29 = new ActionDescriptor();
  desc29.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC01'));
  list4.putObject(cTID('SCnc'), desc29);
  var desc30 = new ActionDescriptor();
  desc30.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC20'));
  list4.putObject(cTID('SCnc'), desc30);
  var desc31 = new ActionDescriptor();
  desc31.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC02'));
  list4.putObject(cTID('SCnc'), desc31);
  var desc32 = new ActionDescriptor();
  desc32.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC19'));
  list4.putObject(cTID('SCnc'), desc32);
  var desc33 = new ActionDescriptor();
  desc33.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC06'));
  list4.putObject(cTID('SCnc'), desc33);
  var desc34 = new ActionDescriptor();
  desc34.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC24'));
  list4.putObject(cTID('SCnc'), desc34);
  var desc35 = new ActionDescriptor();
  desc35.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC24'));
  list4.putObject(cTID('SCnc'), desc35);
  var desc36 = new ActionDescriptor();
  desc36.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC24'));
  list4.putObject(cTID('SCnc'), desc36);
  var desc37 = new ActionDescriptor();
  desc37.putEnumerated(cTID('ncTp'), cTID('STnc'), cTID('NC22'));
  list4.putObject(cTID('SCnc'), desc37);
  desc22.putList(cTID('ovNC'), list4);
  desc22.putBoolean(cTID('ovCM'), false);
  desc22.putBoolean(cTID('ovCW'), true);
  desc22.putBoolean(cTID('ovCU'), true);
  desc22.putBoolean(cTID('ovSF'), true);
  desc22.putBoolean(cTID('ovCB'), true);
  desc22.putString(cTID('ovSN'), "images");
  desc21.putObject(cTID('Usng'), sTID('SaveForWeb'), desc22);
  executeAction(cTID('Expr'), desc21, DialogModes.NO);
}

The script can be a part of an action used for batch of course. So you can open your .psd with an action, maybe do some modifications and then use a script as a last step instead of Save for Web. Also it can be rewritten in a more sophisticated way but who cares.

The result: two jpegs saved in the same folder as my original psd with correct names and sizes: enter image description here

Update:

To use a script in an action you can first save it as a .jsx file in YourPhotoshop/Presets/Scripts folder, restart PS and add it with Insert Menu Item... command from the flyout menu (the script will be located in File > Scripts menu), then it'll appear as a usual step:

enter image description here

4
  • Well, that seems to kind of work. Saved as 'Save2Jpgs.jsx' threw it in scripts, relaunch Ps, tadahhh!! It won't load as an action, whatever I name it, but script will do for me. It was saving both at 90% & only a subset of the exif data. I've figured out how to change the quality, in lines 3 & 4, but is there a switch in there for 'all metadata' like there is in the save for web window? Or is there a list/lookup of what each of the 'codes' are, QChS QCUI etc so I can play with it myself?
    – Tetsujin
    Commented Mar 6, 2020 at 12:01
  • 1
    I've updated my answer with a way to use a script in an action. This part of Photoshop scripting isn't documented, so there are no any lists for the codes, the only way to understand what they do is from experimenting. I reexported my image with All Metadata option and the code on line 46 has changed from 'MDCC' to 'MDAl' — here's the answer Commented Mar 6, 2020 at 13:34
  • @Tetsujin, PS Actions and code generated by the scripting listener record the actions as they are. Whatever code you tried likely had the wrong metadata setting at the time of saving. So if you just recorded the action with all metadata selected, you would get the right output. Xtools by the way also has a script called ActionToJavascript.jsx, which more or less does the same thing, except it converts Actions to javascript. You may find that easier to work with, especially in cases where the action contains multiple steps.
    – Joonas
    Commented Mar 6, 2020 at 13:41
  • tbh, I initially tried 'Load Action' because frankly I haven't a clue what I'm doing ;) I don't really want to install all the xtools stuff just for the very few times I may ever need it & I can't code to save my life ;) I got the script to work, I managed to get it into actions as a Menu Item, but I've now just key-commanded it from the shortcuts pref, which will be the way I'll use it. The last tweak from Sergey gave me the full metadata, so I'm more than happy.
    – Tetsujin
    Commented Mar 6, 2020 at 13:47
0

I'm adding this answer because I came back to this much later, in need of adding a new modification of this script… and I couldn't remember how to make it into an Action.

  1. Make sure your new script is in [Photoshop install location]/Presets/Scripts
    For me /Applications/Adobe Photoshop 2020/Presets/Scripts/Save2JpgsLOW.jsx

  2. Set up a New Action and start Recording

  3. Navigate to File menu>Scripts>Browse - select your new script & Open.

  4. Stop recording. Your script has been added to the Action.

1
  • As an option you can also use Add Menu Item of the Action panel to make sure the script wasn’t call during the action recording (if you don’t want it to run on some random opened document for example) Commented Apr 14, 2023 at 6:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.