low quality jpg resize

Upload Photoshop Scripts, download Photoshop Scripts, Discussion and Support of Photoshop Scripts

Moderators: Tom, Kukurykus

Mike Hale

low quality jpg resize

Post by Mike Hale »

This script is in answer to a post at the Adobe forum. It will resize a jpg image if the image is wider that 800px and the quality is below 5.

It only works with jpg saved by Photoshop. It could be extended to cover other jpg writers but I don't have enough sample images for testing.

It requires exiftool. It also has Xbytor's exec.js included inline.

Code: Select all//
// This script requires Exiftool be installed.
// It will resize jpg images basied on width and compression quailty
// It is written for Windows and CS2
   var minWidth = 800;
   var minQ = 5;
   var resizedFolderStr = 'resized';
   saveOptions = new JPEGSaveOptions();
   saveOptions.embedColorProfile = true;
   saveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
   saveOptions.matte = MatteType.NONE;
   saveOptions.quality = 8; 

function main(){
   var files = getExiftoolData();
   files.sort(sortWidth);
   while(files.length != 0){
      var file = files.shift();
      if(file.w > minWidth){
         if(file.q < minQ){
             var saveFolder = new Folder(file.parent+'/'+resizedFolderStr);
             if(!saveFolder.exists) saveFolder.create();
            var doc = app.open(file);
            fitImage(file.w/2,file.h);
            doc.saveAs(new File(saveFolder+'/'+file.name),saveOptions);
            doc.close();
         };
      };
   };
};
   
function getExiftoolData(){
   var cmdApp = 'exiftool.pl';// Change to full path if not located in dos path
   var widthTag = '-ImageWidth ';
   var heightTag = '-ImageHeight ';
   var jpgQTag = '-PhotoshopQuality ';
   var extTag = '-ext .jpg ';// limit to jpg files
   // not used. Testing returns mixed values depending on jpg writer
   var jpgQAltTags = '-Quality -ImageQuality -ImageQuality2 -MinoltaQuality -QualityMode -SanyoQuality';

   var inputFolder = Folder.selectDialog('Choose the source folder','/c/temp');
   if(inputFolder == null) return;

   var cmdArgs = jpgQTag + widthTag + heightTag + extTag + '"' + inputFolder.fsName;
   var dataFile = new File(exec(cmdApp,cmdArgs));
   $.sleep(5000);//wait for output
   if (!dataFile.exists) return;
   var files = new Array;
   dataFile.open('r');
   while(!dataFile.eof){
      var line = dataFile.readln();
      if(startsWith(line,'========')){
         line = line.replace('======== ','');
         line = line.replace(/\\/g,'/');
         line = line.replace(':','');
         var f = new File('/'+line);
         line = dataFile.readln();
         if(startsWith(line,'Photoshop')){
            line = line.match(/\d+/g);
            f.q = parseInt(line);
            line = dataFile.readln();
            line = line.match(/\d+/g);
            f.w = parseInt(line);
            line = dataFile.readln();
            line = line.match(/\d+/g);
            f.h = parseInt(line);
            files.push(f);
         };
      };
   };
   dataFile.close();
   return files;
};
function startsWith( str, start )  {
   var s = str.substr( 0, start.length );
   return( s == start );
};
function sortWidth(a,b){
   var res = 1;
   if(a.w == b.w) res = 0;
   if(a.w < b.w) res =-1;
   return res;
};
function fitImage(X,Y){
    var desc = new ActionDescriptor();
    desc.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Pxl" ), X );
    desc.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Pxl" ), Y );
executeAction( stringIDToTypeID( "3caa3434-cb67-11d1-bc43-0060b0a13dc4" ), desc, DialogModes.NO );
};

//
// exec.js
//    Execute external applications in PSCS-JS
//
// Usage:
//    exec(cmd[, args])
//    bash(cmd[, args])
//      Executes the command 'cmd' with optional arguments. The
//      name of the file containing the output of that command
//      is returned.
//
// Examples:
//    exec("i_view32.exe", "/slideshow=c:\\images\\");
//
//    f = bash("~/exif/exifdump", fileName);
//    data = loadFile(f);
//
// Notes
//   The use of bash on XP requires that cygwin be installed.
//   Paths in the ExecOptions are XP paths. I'll put mac stuff
//      in later. Change if you don't like it.
//
// $Id: exec.js,v 1.4 2005/09/30 17:03:01 anonymous Exp $
// Copyright: (c)2005, xbytor
// License: http://creativecommons.org/licenses/LGPL/2.1
// Contact: xbytor@gmail.com
//

function ExecOptions() {
  var self = this;
  self.tempdir       = "c:\\temp\\";
  self.bash          = "c:\\cygwin\\bin\\bash";
  self.scriptPrefix  = "doExec-";
  self.captureOutput = true;
  self.captureFile   = "doExec.out"; // set this to undefined to get
                                     // a unique output file each time
  self.outputPrefix  = "doExec-";
};

function ExecRunner(opts) {
  var self = this;

  self.opts = opts || new ExecOptions();

  self.bash = function bash(exe, args) {
    var self = this;
    return self.doExec(self.opts.bash, "-c \"" + exe + " "  +
                       (args || ''), "  2>&1");
  };

  self.exec = function exec(exe, args) {
    var self = this;
    return self.doExec(exe, (args || ''), "");
  };

  self.doExec = function doExec(exe, args, redir) {
    var self = this;
    var opts = self.opts;
    if (exe == undefined) { throw "Must specify program to exec"; }

    args = (!args) ? '' : ' ' + args;

    // create a (hopefully) unique script name
    var ts = new Date().getTime();
    var scriptName = opts.tempdir + opts.scriptPrefix + ts + ".bat";

    var cmdline = exe + args;   // the command line in the .bat file
   
    // redirected output handling
    var outputFile = undefined;
    if (opts.captureOutput) {
      if (opts.captureFile == undefined) {
        outputFile = opts.tempdir + opts.outputPrefix + ts + ".out";
      } else {
        outputFile = opts.tempdir + opts.captureFile;
        new File(outputFile).remove();
      }
      // stderr redirect in cygwin
      cmdline += "\" > \"" + outputFile + "\" " + redir;
    }
   
    var script = new File(scriptName);
    if (!script.open("w")) {
      throw "Unable to open script file: " + script.fsName;
    }
    script.writeln(cmdline);
    script.close();
    if (!script.execute()) {
      throw "Execution failed for " + script.fsName;
    }
    return outputFile;
  }
}

function bash(exe, args) {
  return (new ExecRunner()).bash(exe, args, " 2>&1");
}
function exec(exe, args) {
  return (new ExecRunner()).exec(exe, args, "");
};

main();