Alter existing script, save extra jpg resized.

Discussion of Automation, Image Workflow and Raw Image Workflow

Moderators: Tom, Kukurykus

bazcraig

Alter existing script, save extra jpg resized.

Post by bazcraig »

Hi Everyone, i was wondering if anyone can help? We're looking for an event script that will save an extra jpg resized to fit 2000px on the longest edge. So far we have this Frankenstein script. But its getting us nowhere. Any help would be greatly appreciated.

Code: Select all// (c) Copyright 2005.  Adobe Systems, Incorporated.  All rights reserved.

/*
@@@BUILDINFO@@@ Save Extra JPEG.jsx 1.0.0.0
*/

var begDesc = "$$$/JavaScripts/SaveExtraJPEG/Description=This script is designed to be used as a script that runs after a save event. The script will save an extra JPEG file next to the current active document. This script does not handle 'as a copy' when saving." // endDesc


// on localized builds we pull the $$$/Strings from a .dat file, see documentation for more details
$.localize = true;

try {

   if ( UsingAsACopy( arguments[0] ) ) {
      alert(    localize( '$$$/JavaScripts/SaveExtraJPEGWarning=Save used As A Copy, extra file may not save correctly.' ) );
   }
   
   var data = GetDataFromDocument( activeDocument );

   // if the current save was not a JPEG then save an extra JPEG
   // JPEG does not support Bitmap mode    
    if ( 'jpg'  != data.extension.toLowerCase() &&
         'JPEG' != data.fileType &&
         DocumentMode.BITMAP != activeDocument.mode ) {

      SaveExtraJPEG( data );

    }

} // try end

catch( e ) {
   // always wrap your script with try/catch blocks so you don't stop production
   // remove comments below to see error for debugging
   // alert( e );
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// Function: SaveExtraJPEG
// Use: save the current document as a copy using JPEG options
// Input: a document must be active
// Params: folder, filename, extension
// Output: file saved as a copy next to the current active document
///////////////////////////////////////////////////////////////////////////////
function SaveExtraJPEG( data ) {
      // 'Save for Web' would be better but I'm lazy
        var jpegOptions = new JPEGSaveOptions();
        jpegOptions.quality = 12; // really low
        jpegOptions.embedColorProfile = false; // really small
       
        // are we using extensions on this save
        var jpegExtension = '.jpg';
      var startRulerUnits;
      var startTypeUnits;
      var startDisplayDialogs;

        if ( "" == data.extension ) {
         jpegExtension = "";
      }

   startDisplayDialogs = displayDialogs;
   startRulerUnits = preferences.rulerUnits;
   startTypeUnits = preferences.typeUnits;
   
   displayDialogs = DialogModes.NO;
   preferences.rulerUnits = Units.PIXELS;
   preferences.typeUnits = TypeUnits.PIXELS;
   //find out longest edge
   var H = ActiveDocument.height;
   var W = ActiveDocument.Width;
   //var Longestedge;
   var NewHeight;
   var NewWidth;
   
   if (W/H >= 1.0)
   {
      //Longestedge = "Width";
      //landscape
      NewWidth = 2000;
      NewHeight = (NewWidth / W * H);
      }
   if (W/H < 1.0)
   {
      //Longestedge = "Height";
      NewHeight = 2000;
      NewWidth = (NewHeight / H * W);
      }

   
   //resize
   activeDocument.resizeImage( NewWidth, NewHeight, 72, ResampleMethod.BICUBIC );



   displayDialogs = startDisplayDialogs;
   preferences.rulerUnits = startRulerUnits;
   preferences.typeUnits = startTypeUnits;

        // third option is as a copy, set that to true
        // so the activeDocument doesn't switch underneath the user
        activeDocument.saveAs( File( data.folder +
                                     '/' +
                                     data.fileName +
                                     jpegExtension ), jpegOptions, true );
}

///////////////////////////////////////////////////////////////////////////////
// Function: UsingAsACopy
// Use: find out if the user used 'As A Copy'
// Input: action descriptor from the event that just occured
// Output: boolean that 'As A Copy' was checked
// Note: On script events the script gets passed in the actual action that
// occured we can look inside the action descriptor and pull information out
// in this case we are looking for the keyCopy
///////////////////////////////////////////////////////////////////////////////
function UsingAsACopy( actionDescriptor ) {
   var usingKeyCopy = false;
   if ( undefined != actionDescriptor ) {
      if ( "ActionDescriptor" == actionDescriptor.typename ) {
         var keyCopy = charIDToTypeID( "Cpy " );
         if ( actionDescriptor.hasKey( keyCopy ) ) {
            usingKeyCopy = actionDescriptor.getBoolean( keyCopy );
         }
      }
   }
   return usingKeyCopy;
}

///////////////////////////////////////////////////////////////////////////////
// Function: GetDataFromDocument
// Usage: pull data about the document passed in
// Input: document to gather data
// Output: Object containing folder, fileName, fileType, extension
///////////////////////////////////////////////////////////////////////////////
function GetDataFromDocument( inDocument ) {
   var data = new Object();
   var fullPathStr = inDocument.fullName.toString();
   var lastDot = fullPathStr.lastIndexOf( "." );
   var fileNameNoPath = fullPathStr.substr( 0, lastDot );
   data.extension = fullPathStr.substr( lastDot + 1, fullPathStr.length );
   var lastSlash = fullPathStr.lastIndexOf( "/" );
   data.fileName = fileNameNoPath.substr( lastSlash + 1, fileNameNoPath.length );
   data.folder = fileNameNoPath.substr( 0, lastSlash );
   data.fileType = inDocument.fullName.type;
   return data;
}
Mike Hale

Alter existing script, save extra jpg resized.

Post by Mike Hale »

What do you want the event script to do that this does not do?

It looks to me like it will save an extra jpg if the doc was not saved as a jpg. Because it uses the activeDocument info it may not save correctly if the file was saved using as a copy.
bazcraig

Alter existing script, save extra jpg resized.

Post by bazcraig »

We want it to save out an extra jpg resized at 2000px on the longest edge Then return us to the unresizd file.
Mike Hale

Alter existing script, save extra jpg resized.

Post by Mike Hale »

Try this

Code: Select all// adapted from Save Extra JPEG.jsx 1.0.0.0 (c) Copyright 2005.  Adobe Systems, Incorporated.  All rights reserved.
// this is a save event script that will resize and save a extra jpg copy of the saved document
// using either the folder and name of the activeDocument + a sufix or the folder and
// name from the saveAs dialog + a sufix. It will over write a file that has the same name as the one used in this scirpt
// it will not save an extra jpg file if the doc mode is bitmap

// note the save event does not occur is the file was saved as part of close event.
// so this script attached to the save event will not make a copy of documents saved that way

// start user options
extraSaveAsOptions = new Object();
    extraSaveAsOptions.longestSide = 2000;// size in pixels to resize
    extraSaveAsOptions.useSaveAsFolder = true;// true = save the extra jpg in the same folder used in the saveAs. false = save in activeDocument folder.
    extraSaveAsOptions.saveSufix = '_2000';
    extraSaveAsOptions.useSFW = true;// true = save for web save. false = normal jpg save
   
// used if useSFW = false
var jpgOptions = new JPEGSaveOptions();
    jpgOptions.embedColorProfile = false;
    jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
    jpgOptions.matte = MatteType.NONE;
    jpgOptions.quality = 8; // 0 -12, low - high quality

// used if useSFW = true
var sfwOptns = new ExportOptionsSaveForWeb();
   sfwOptns.format = SaveDocumentType.JPEG;
   sfwOptns.includeProfile = false;
   sfwOptns.interlaced = false;
   sfwOptns.lossy = 0;
   sfwOptns.optimized = true;
   sfwOptns.quality = 40; //0 - 100, low - high quality
// end user options

try {
   extraSaveAsOptions.sData = getSaveData( arguments[0] );// get data from the save event descriptor   
   var data = GetDataFromDocument( activeDocument );// get data from doc

   // JPEG does not support Bitmap mode   
    if ( DocumentMode.BITMAP != activeDocument.mode ) {
      var hs = activeDocument.activeHistoryState;// save historyState to undo resize
      fitImage( extraSaveAsOptions.longestSide, extraSaveAsOptions.longestSide );
      SaveAsExtraJPEG( data, extraSaveAsOptions );
      activeDocument.activeHistoryState = hs;// undo resize
   }

} // try end

catch( e ) {
   // always wrap your script with try/catch blocks so you don't stop production
   // remove comments below to see error for debugging
   // alert( e );
}

///////////////////////////////////////////////////////////////////////////////
// Function: SaveExtraJPEG
// Use: save the current document as a copy using extraSaveAsOptions
// Input: a document must be active
// Params: activeDoc data, extraSaveAsOptions
// Output: file saved as a copy from the current active document
///////////////////////////////////////////////////////////////////////////////
function SaveAsExtraJPEG( data, extraSaveAsOptions ) {
   
   if( extraSaveAsOptions.useSaveAsFolder && extraSaveAsOptions.savedAs ) {// use saveAs dialog folder and name
      var saveFolder = extraSaveAsOptions.sData.folder;
      var saveName = extraSaveAsOptions.sData.saveName;
   }else{// use activeDocument folder and name
      var saveFolder = data.folder;
      var saveName = data.name;
   }
   if( extraSaveAsOptions.useSFW ){
      activeDocument.exportDocument( File( saveFolder + '/' + saveName + extraSaveAsOptions.saveSufix + '.jpg' ), ExportType.SAVEFORWEB, sfwOptns );
   }else{
        activeDocument.saveAs( File( saveFolder + '/' + saveName + extraSaveAsOptions.saveSufix + '.jpg' ), jpgOptions, true );
   }
}

///////////////////////////////////////////////////////////////////////////////
// Function: getSaveData
// Use: find user save settings
// Input: action descriptor from the event that just occured
// Output: object with save options
// Note: On script events the script gets passed in the actual action that
// occured we can look inside the action descriptor and pull information out
///////////////////////////////////////////////////////////////////////////////
function getSaveData( actionDescriptor ) {
   var usingKeyCopy = false;
   var saveData = {};
   saveData.savedAs = false;
   if ( undefined != actionDescriptor ) {
      if ( "ActionDescriptor" == actionDescriptor.typename ) {
         if ( actionDescriptor.hasKey( charIDToTypeID( "Cpy " ) ) ) {
            saveData.asCopy = actionDescriptor.getBoolean( charIDToTypeID( "Cpy " ) );
         }
      if( actionDescriptor.hasKey( stringIDToTypeID('in') ) ) {// check to see if saveAs instead of normal save
         saveData.savedAs = true;
         if( actionDescriptor.getPath( stringIDToTypeID('in') ) instanceof Folder ) { // returns folder if name not changed in dialog
            saveData.folder = decodeURI( actionDescriptor.getPath( stringIDToTypeID('in') ) );
            saveData.name = decodeURI ( activeDocument.name );// get name from activeDoc
            saveData.name = saveData.name.match( /(.*)(\.[^\.]+)/ ) ? saveData.name = saveData.name.match( /(.*)(\.[^\.]+)/ ) : saveData.name = [ saveData.name, saveData.name, undefined ];
            saveData.extension = saveData.name[ 2 ];
            saveData.saveName = saveData.name[ 1 ];
         }
         if( actionDescriptor.getPath( stringIDToTypeID('in') ) instanceof File ) { // returns file if name was changed in dialog
            saveData.folder = decodeURI( actionDescriptor.getPath( stringIDToTypeID('in') ).parent );
            saveData.name = decodeURI( actionDescriptor.getPath( stringIDToTypeID('in') ).name );// get name from save dialog
            saveData.name = saveData.name.match( /(.*)(\.[^\.]+)/ ) ? saveData.name = saveData.name.match( /(.*)(\.[^\.]+)/ ) : saveData.name = [ saveData.name, saveData.name, undefined ];
            saveData.extension = saveData.name[ 2 ];
            saveData.saveName = saveData.name[ 1 ];
         }
      }
       }
   }
   return saveData;
}

///////////////////////////////////////////////////////////////////////////////
// Function: GetDataFromDocument
// Usage: pull data about the document passed in
// Input: document to gather data
// Output: Object containing folder, fileName, fileType, extension
///////////////////////////////////////////////////////////////////////////////
function GetDataFromDocument( inDocument ) {
   var data = new Object();
   var docName = decodeURI ( inDocument.name );
   docName = docName.match( /(.*)(\.[^\.]+)/ ) ? docName = docName.match( /(.*)(\.[^\.]+)/ ) : docName = [ docName, docName, undefined ];
   data.extension = docName[ 2 ];
   data.name = docName[ 1 ];
   data.folder = decodeURI ( inDocument.path );
   return data;
}

///////////////////////////////////////////////////////////////////////////////
// Function: fitImage
// Usage: resize image
// Input: h, w in pixlels
// Output: None
///////////////////////////////////////////////////////////////////////////////
function fitImage( w, h ){
    var fitImage = stringIDToTypeID( "3caa3434-cb67-11d1-bc43-0060b0a13dc4" );
    var size = new ActionDescriptor();
    size.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Pxl" ), w );
    size.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Pxl" ), h );
    executeAction( fitImage, size, DialogModes.NO );
}
bazcraig

Alter existing script, save extra jpg resized.

Post by bazcraig »

unbelievable, works perfectly. I cant thank you enough! you really should have a 'buy me a beer' button.

There is one more, tiny, request. If i wanted to add in 'sharpen' then 'fade on luminosity' to the jpgs would this be possible?

I am very happy to try and work this out for myself, but possibly some help on where abouts in the code i should look to add the new lines? i really cant thank you enough, i hope it didnt take you too long
Mike Hale

Alter existing script, save extra jpg resized.

Post by Mike Hale »

Most of the sharpen methods can be found in the artlayer object methods listed in the javascript guide.

For smart sharpen you will need either the scriptlistner plugin that ships with Photoshop or Xbytor's stdlib.js from his xtools. See http://ps-scripts.com/bb/viewtopic.php?t=2807 and http://ps-scripts.sourceforge.net/xtools.html

For fade you will need scriptlistner ( fade does not seem to be part of stdlib.js ) or here is a version that uses luminosity blend modeCode: Select allfunction fade(amount){// amount in percent: 0 - 100
    var desc = new ActionDescriptor();
    desc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), amount );
    desc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Lmns" ) );
executeAction( charIDToTypeID( "Fade" ), desc, DialogModes.NO );
}

I would put the fade function some where near the bottom of the script with the other functions. Then between

fitImage( extraSaveAsOptions.longestSide, extraSaveAsOptions.longestSide );

and

SaveAsExtraJPEG( data, extraSaveAsOptions );

Do something like thisCode: Select allif(activeDocument.layers.length > 1 ) activeDocument.flatten();// if the doc has layers flatten before sharpen
activeDocument.activeLayer.applyUnSharpMask( 100, .8, 0 );//amount, radius, threshold
fade( 50 );

As for the beer, I owe X a few. If you feel the need you can send one his way through paypal at xbytor@gmail.com

Mike