11 Replies Latest reply on Dec 29, 2017 3:37 AM by akribie

    Batch save to multiple folders

    Janice Welton

      Wondering if anyone can help- I am stumped!

       

      I have a number of sub-folders with hi-res tiff images that I would like  to process.

      Is there any way to run a batch that uses "Include All Subfolders" to process images and save to multiple sub-folders with the same name as the original sub-folders?

       

      For example sub-folder 1 (containing hi-res images) is located here: C:\Event_Photos\hi_res\May28

      For example sub-folder 2 (containing hi-res images) is located here: C:\Event_Photos\hi_res\May29

       

      The batch would process the sub-folders and save to jpeg in the following folders:

       

      C:\Event_Photos\lo-res\May28

      C:\Event_Photos\lo-res\May29

       

      But.. without hard coding the folder names into the script/action.

       

      Any help would be appreciated!

        • 1. Re: Batch save to multiple folders
          Muppet Mark-QAl63s Level 4

          With batching Actions you can check the 'Include all Subfolders' checkbox and it will recurse the folders for your files but it does not deal with saving back to each of the files parent folder within the folder structure. Im NOT sure if 'Image Processor' in newer versions of Photoshop than what I have does this have you looked at that? If it does NOT then a script CAN do this for you…

          • 2. Re: Batch save to multiple folders
            Janice Welton Level 1

            I am using CS4, and the Image Processor only saves to folders via format.

            Would prefer to use scripting to give more flexibility anyway.

             

            Thanks for responding.

            • 3. Re: Batch save to multiple folders
              Paul Riggott Level 6

              Could you try this...

              #target Photoshop
              app.bringToFront();
              function main(){
              var win = new Window( 'dialog', 'Compliments Adobe Forum' ); 
              g = win.graphics;
              var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.99, 0.99, 0.99, 1]);
              g.backgroundColor = myBrush;
              win.alignChildren="row";
              win.g10 = win.add('group');
              win.g10.orientation = "row";
              win.title = win.g10.add('statictext',undefined,'Batch Process Tiff Files');
              win.title.alignment="bottom";
              var g = win.title.graphics;
              g.font = ScriptUI.newFont("Georgia","BOLDITALIC",22);
              win.p1= win.add("panel", undefined, undefined, {borderStyle:"black"}); 
              win.p1.alignChildren="fill";
              win.g20 =win.p1.add('group');
              win.g20.cb1 = win.g20.add('statictext',undefined,'Please Select Top Level Folder :-');
              win.g25 =win.p1.add('group');
              win.g25.spacing=10;
              win.g25.orientation = 'row';
              win.g25.alignment="left";
              win.g25.et1 = win.g25.add('edittext',undefined,'');
              win.g25.et1.preferredSize=[300,20];
              win.g25.et1.enabled=false;
              win.g25.bu1 = win.g25.add('button',undefined,'Browse');
              win.g25.bu1.onClick = function() {
                imageFolder = Folder.selectDialog("Please select the top level folder"); 
               if(imageFolder !=null){
                win.g25.et1.text =  decodeURI(imageFolder.fsName); 
                }
              }
              win.g29 =win.p1.add('group');
              win.g29.spacing=0;
              win.g29.orientation = 'row';
              win.g29.alignment="left";
              win.g29.cb1 = win.g29.add('checkbox',undefined,'Resize to fit');
              win.g29.cb1.preferredSize=[120,20];
              win.g29.st1 = win.g29.add('statictext',undefined,'W: ');
              win.g29.et1 = win.g29.add('edittext',undefined,'')
              win.g29.et1.preferredSize=[50,20];
              win.g29.st2 = win.g29.add('statictext',undefined,'px');
              win.g29.st2.preferredSize=[100,20];
              win.g29.st3 = win.g29.add('statictext',undefined,'H: ');
              win.g29.et2 = win.g29.add('edittext',undefined,'');
              win.g29.et2.preferredSize=[50,20];
              win.g29.st4 = win.g29.add('statictext',undefined,'px');
              win.g29.et1.enabled=false; 
              win.g29.et2.enabled=false;
              win.g29.cb1.onClick = function(){
                  if(win.g29.cb1.value){
                      win.g29.et1.enabled=true;
                      win.g29.et1.active=true;
                      win.g29.et2.enabled=true;    
                      }else{
                          win.g29.et1.enabled=false;
                          win.g29.et2.enabled=false;
                          }
              }
              win.g29.et1.onChanging = function() { 
                if (this.text.match(/[^\-\.\d]/)) { 
                  this.text = this.text.replace(/[^\-\.\d]/g, ''); 
                } 
              };
              win.g29.et2.onChanging = function() { 
                if (this.text.match(/[^\-\.\d]/)) { 
                  this.text = this.text.replace(/[^\-\.\d]/g, ''); 
                } 
              };
              win.g30 =win.p1.add('group');
              win.g30.spacing=10;
              win.g30.orientation = 'row';
              win.g30.alignment="left";
              win.g30.cb1 = win.g30.add('checkbox',undefined,'Run Action 1');
              win.g30.dd1 = win.g30.add('dropdownlist');
              win.g30.dd1.preferredSize=[150,20];
              win.g30.dd2 = win.g30.add('dropdownlist');
              win.g30.dd2.preferredSize=[150,20];
              win.g30.dd1.enabled=false; 
              win.g30.dd2.enabled=false;
              win.g30.cb1.onClick = function(){
                  if(win.g30.cb1.value){
                      win.g30.dd1.enabled=true;
                      win.g30.dd2.enabled=true;    
                      }else{
                          win.g30.dd1.enabled=false;
                          win.g30.dd2.enabled=false;
                          }
              }
              win.p2= win.p1.add("panel", undefined, undefined, {borderStyle:"black"}); 
              win.p2.preferredSize=[400,2];
              win.p1.st1 = win.p1.add('statictext',undefined,"Save As :-");
              var z = win.p1.st1.graphics;
              z.font = ScriptUI.newFont("Georgia","BOLDITALIC",18);
              win.g65 =win.p1.add('group');
              win.g65.spacing=10;
              win.g65.orientation = 'row';
              win.g65.alignment="left";
              win.g65.cb1 = win.g65.add('checkbox',undefined,"JPG");
              win.g65.st1 = win.g65.add('statictext',undefined,"Quality :-");
              var jpgQuality=[1,2,3,4,5,6,7,8,9,10,11,12];
              win.g65.dd1 = win.g65.add('dropdownlist',undefined,jpgQuality);
              win.g65.dd1.selection=7;
              win.g65.dd1.enabled=false;
              win.g65.cb1.onClick = function(){
                  if(win.g65.cb1.value){
                      win.g65.dd1.enabled=true;
                      win.g70.cb1.value=false;
                      win.g70.dd1.enabled=false;
                      win.g70.dd2.enabled=false;
                      win.g70a.cb1.enabled=false;
                      win.g70a.cb2.enabled=false;
                      win.g70a.cb3.enabled=false;
                      }else{
                          win.g65.dd1.enabled=false;
                          }
              }
              win.p3= win.p1.add("panel", undefined, undefined, {borderStyle:"etched"});
              win.g70 =win.p3.add('group');
              win.g70.spacing=10;
              win.g70.orientation = 'row';
              win.g70.alignment="left";
              win.g70.cb1 = win.g70.add('checkbox',undefined,"Save For Web");
              win.g70.dd1 = win.g70.add('dropdownlist');
              for(var a = 1;a<101;a++){
                  win.g70.dd1.add('item', a);
                  }
              win.g70.dd1.selection=79;
              win.g70.dd2 = win.g70.add('dropdownlist');
              var MetaList = [['No Metadata','MDNn'],
                    ['All Metadata','MDAl'],
                    ['Copyright','MDCp' ],
                    ['Copyright and Contact Info','MDCC'],
                    ['All Except Camera Info','MDAx']];
               for (var i in MetaList) {
               win.g70.dd2.add('item',MetaList[i][0]);
              }
              win.g70.dd2.selection=0;
              win.g70.dd2.enabled=false;
              win.g70.dd1.enabled=false;
              win.g70.cb1.onClick = function(){
                  if(win.g70.cb1.value){
                      win.g70.dd1.enabled=true;
                      win.g70.dd2.enabled=true;
                      win.g65.cb1.value=false;
                      win.g65.dd1.enabled=false;
                      win.g70a.cb1.enabled=true;
                      win.g70a.cb2.enabled=true;
                      win.g70a.cb3.enabled=true;
                      }else{
                          win.g70.dd1.enabled=false;
                          win.g70.dd2.enabled=false;
                          win.g70a.cb1.enabled=false;
                          win.g70a.cb2.enabled=false;
                          win.g70a.cb3.enabled=false;
                          }
              }
              win.g70a =win.p3.add('group');
              win.g70a.spacing=10;
              win.g70a.orientation = 'row';
              win.g70a.alignment="left";
              win.g70a.cb1 = win.g70a.add('checkbox',undefined,"Embed Profile");
              win.g70a.cb2 = win.g70a.add('checkbox',undefined,"sRGB");
              win.g70a.cb3 = win.g70a.add('checkbox',undefined,"Progressive");
              win.g70a.cb2.value=true;
              win.g70a.cb1.enabled=false;
              win.g70a.cb2.enabled=false;
              win.g70a.cb3.enabled=false;
              win.g150 =win.p1.add('group');
              win.g150.spacing=10;
              win.g150.orientation = 'row';
              win.g150.alignment="top";
              win.g150.bu1 = win.g150.add('button',undefined,"Process");
              win.g150.bu1.preferredSize=[200,20];
              win.g150.bu2 = win.g150.add('button',undefined,"Cancel");
              win.g150.bu2.preferredSize=[200,20];
              if (app.version.match(/\d+/) ==10){
                  win.g70.dd2.visible=false;
                  win.g70a.cb2.visible=false;
                   win.g70a.cb3.visible=false;
                  }
              var actionSets = new Array();
              actionSets = getActionSets();
              for (var i=0,len=actionSets.length;i<len;i++) {
               win.g30.dd1.add ('item', "" + actionSets[i]);  
              }; 
              win.g30.dd1.selection=0;
              var actions = new Array(); 
              actions = getActions(actionSets[0]);
              for (var i=0,len=actions.length;i<len;i++) {
               win.g30.dd2.add ('item', "" + actions[i]);    
              };
              win.g30.dd2.selection=0;
              win.g30.dd1.onChange = function() {
              win.g30.dd2.removeAll();
              actions = getActions(actionSets[parseInt(this.selection)]);
              for (var i=0,len=actions.length;i<len;i++) {
               win.g30.dd2.add ('item', "" + actions[i]);  
               }
               win.g30.dd2.selection=0;
              };
              win.g150.bu1.onClick = function(){
                  if(win.g25.et1.text == '') {
                      alert("No Folder Has Been Selected!");
                      return;
                      }
                  if(win.g29.cb1.value && win.g29.et1.text == ''){
                      alert("No Resize Width Has Been Entered!");
                      return;
                      }
                  if(win.g29.cb1.value && win.g29.et2.text == ''){
                      alert("No Resize Height Has Been Entered!");
                      return;
                      }
                  if(!win.g65.cb1.value && !win.g70.cb1.value){
                      alert("No Save FileType Has Been Selected!");
                      return;
                      }
                  if(win.g29.cb1.value){
               var WIDTH = parseInt(win.g29.et1.text);
               var HEIGHT= parseInt(win.g29.et2.text);
               if((isNaN(WIDTH)) || (WIDTH < 1)){
                     alert( "Not a valid entry!\nResize Width MUST be greater than 1.");
                     return;
                     }
               if((isNaN(HEIGHT)) || (HEIGHT < 1)){
                      alert( "Not a valid entry!\nResize Height MUST be greater than 1.");
                      return;
               }
              }
                  win.close(1);
                  process();
              }
              win.show();
              function process(){
              folderList=[];
              if (imageFolder != null)  {
               processFolder(imageFolder); 
                  folderList.unshift(imageFolder);
               for (var a =0;a<folderList.length;a++){
               processFiles(folderList[a]); 
               }
              }
              }
              function processFiles(folder){
              var tiffs = folder.getFiles ("*.tif");
              if(tiffs.length == 0) return;
              var OrginalFolder = folder;
              var OrginalFolderName = OrginalFolder.name;
              var destParent = Folder(decodeURI(OrginalFolder.parent).replace(/hi/gi,'lo'));
              if(!destParent.exists) destParent.create();
              var destFolder = Folder(destParent+"/"+ OrginalFolderName);
              if(!destFolder.exists) destFolder.create();
              for (var a in tiffs){
              open(tiffs[a]);
              var Name = decodeURI(tiffs[a].name).replace(/\.[^\.]+$/, '');
              var saveFile = File(destFolder+"/"+Name+".jpg");
              var doc = activeDocument;
              doc.flatten();
              if (doc.bitsPerChannel != BitsPerChannelType.EIGHT) doc.bitsPerChannel = BitsPerChannelType.EIGHT;
              activeDocument.pathItems.removeAll();
              if(win.g29.cb1.value) FitImage( parseInt(win.g29.et1.text), parseInt(win.g29.et2.text) );
              if(win.g30.cb1.value){
                  doAction(win.g30.dd2.selection.text, win.g30.dd1.selection.text);
                  doc.flatten();
                  }
              if(win.g65.cb1.value) SaveJPEG(saveFile, (Number(win.g65.dd1.selection.index)+1));
              if (app.version.match(/\d+/) == 10 && win.g70.cb1.value){//SFW CS3
                  SaveForWebCS3(saveFile,(Number(win.g70.dd1.selection.index)+1),win.g70a.cb1.value);
              }
              if (app.version.match(/\d+/) > 10 && win.g70.cb1.value){//SFW CS4or5
                  var Quality = Number(win.g70.dd1.selection.index)+1;
                  var Profile ='';
               if(win.g70a.cb2.value ? Profile = 'CHsR' : Profile = 'CHDc' );
                  var MetaData = MetaList[Number(win.g70.dd2.selection.index)][1];
                  var Progressive = 1;
                  if(win.g70a.cb3.value)  Progressive = 3;
                  var Embed = win.g70a.cb1.value;
                  CS4orCS5SFW(saveFile,Quality,MetaData,Profile,Progressive,Embed);
              }
              app.activeDocument.close(SaveOptions.DONOTSAVECHANGES); 
                  }
              }
              function getActionSets() { 
              cTID = function(s) { return app.charIDToTypeID(s); }; 
              sTID = function(s) { return app.stringIDToTypeID(s); }; 
                var i = 1; 
                var sets = [];  
                while (true) { 
                  var ref = new ActionReference(); 
                  ref.putIndex(cTID("ASet"), i); 
                  var desc; 
                  var lvl = $.level; 
                  $.level = 0; 
                  try { 
                    desc = executeActionGet(ref); 
                  } catch (e) { 
                    break;    // all done 
                  } finally { 
                    $.level = lvl; 
                  } 
                  if (desc.hasKey(cTID("Nm  "))) { 
                    var set = {}; 
                    set.index = i; 
                    set.name = desc.getString(cTID("Nm  ")); 
                    set.toString = function() { return this.name; }; 
                    set.count = desc.getInteger(cTID("NmbC")); 
                    set.actions = []; 
                    for (var j = 1; j <= set.count; j++) { 
                      var ref = new ActionReference(); 
                      ref.putIndex(cTID('Actn'), j); 
                      ref.putIndex(cTID('ASet'), set.index); 
                      var adesc = executeActionGet(ref); 
                      var actName = adesc.getString(cTID('Nm  ')); 
                      set.actions.push(actName); 
                    } 
                    sets.push(set); 
                  } 
                  i++; 
                } 
                return sets; 
              }; 
              function getActions(aset) {
              cTID = function(s) { return app.charIDToTypeID(s); }; 
              sTID = function(s) { return app.stringIDToTypeID(s); };
                var i = 1;
                var names = [];
                if (!aset) {
                  throw "Action set must be specified";
                }  
                while (true) {
                  var ref = new ActionReference();
                  ref.putIndex(cTID("ASet"), i);
                  var desc;
                  try {
                    desc = executeActionGet(ref);
                  } catch (e) {
                    break;    
                  }
                  if (desc.hasKey(cTID("Nm  "))) {
                    var name = desc.getString(cTID("Nm  "));
                    if (name == aset) {
                      var count = desc.getInteger(cTID("NmbC"));
                      var names = [];
                      for (var j = 1; j <= count; j++) {
                        var ref = new ActionReference();
                        ref.putIndex(cTID('Actn'), j);
                        ref.putIndex(cTID('ASet'), i);
                        var adesc = executeActionGet(ref);
                        var actName = adesc.getString(cTID('Nm  '));
                        names.push(actName);
                      }
                      break;
                    }
                  }
                  i++;
                }
                return names;
              };
              function processFolder(folder) {
                  var fileList = folder.getFiles()
                   for (var i = 0; i < fileList.length; i++) {
                      var file = fileList[i];
              if (file instanceof Folder) { 
               folderList.push(file);  
                  processFolder(file);
                  }
                 }
              }
              function FitImage( inWidth, inHeight ) {
               var desc = new ActionDescriptor();
               var unitPixels = charIDToTypeID( '#Pxl' );
               desc.putUnitDouble( charIDToTypeID( 'Wdth' ), unitPixels, inWidth );
               desc.putUnitDouble( charIDToTypeID( 'Hght' ), unitPixels, inHeight );
               var runtimeEventID = stringIDToTypeID( "3caa3434-cb67-11d1-bc43-0060b0a13dc4" ); 
               executeAction( runtimeEventID, desc, DialogModes.NO );
              };
              function SaveJPEG(saveFile, jpegQuality){
              jpgSaveOptions = new JPEGSaveOptions();
              jpgSaveOptions.embedColorProfile = true;
              jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
              jpgSaveOptions.matte = MatteType.NONE;
              jpgSaveOptions.quality = jpegQuality; 
              activeDocument.saveAs(saveFile, jpgSaveOptions, true,Extension.LOWERCASE);
              }
              function SaveForWebCS3(saveFile,jpegQuality,Profile) {
              if(Profile == undefined) Profile = false;
              var sfwOptions = new ExportOptionsSaveForWeb(); 
                 sfwOptions.format = SaveDocumentType.JPEG; 
                 sfwOptions.includeProfile = Profile; 
                 sfwOptions.interlaced = 0; 
                 sfwOptions.optimized = true; 
                 sfwOptions.quality = jpegQuality;
              activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
              }
              function CS4orCS5SFW(FileName,Quality,MetaData,Profile,Progressive,Embed) {
                  var desc7 = new ActionDescriptor();
                      var desc8 = new ActionDescriptor();
                      desc8.putEnumerated( charIDToTypeID('Op  '), charIDToTypeID('SWOp'), charIDToTypeID('OpSa') );
                      desc8.putEnumerated( charIDToTypeID('Fmt '), charIDToTypeID('IRFm'), charIDToTypeID('JPEG') );
                      desc8.putBoolean( charIDToTypeID('Intr'), false );
                      desc8.putInteger( charIDToTypeID('Qlty'), Quality );
                      desc8.putInteger( charIDToTypeID('QChS'), 0 );
                      desc8.putInteger( charIDToTypeID('QCUI'), 0 );
                      desc8.putBoolean( charIDToTypeID('QChT'), false );
                      desc8.putBoolean( charIDToTypeID('QChV'), false );
                      desc8.putBoolean( charIDToTypeID('Optm'), true );
                      desc8.putInteger( charIDToTypeID('Pass'), Progressive ); 
                      desc8.putDouble( charIDToTypeID('blur'), 0.000000 );
                      desc8.putBoolean( charIDToTypeID('EICC'), Embed ); 
                      desc8.putBoolean( charIDToTypeID('Mtt '), false );
                      desc8.putInteger( charIDToTypeID('MttR'), 255 );
                      desc8.putInteger( charIDToTypeID('MttG'), 255 );
                      desc8.putInteger( charIDToTypeID('MttB'), 255 );
                      desc8.putBoolean( charIDToTypeID('SHTM'), false );
                      desc8.putBoolean( charIDToTypeID('SImg'), true );
                      desc8.putEnumerated( charIDToTypeID('SWch'), charIDToTypeID('STch'), charIDToTypeID(Profile) );
                      desc8.putEnumerated( charIDToTypeID('SWmd'), charIDToTypeID('STmd'), charIDToTypeID(MetaData) );
                      desc8.putBoolean( charIDToTypeID('SSSO'), false );
                          var list2 = new ActionList();
                      desc8.putList( charIDToTypeID('SSLt'), list2 );
                      desc8.putBoolean( charIDToTypeID('DIDr'), false );
                      desc8.putPath( charIDToTypeID('In  '), new File( FileName ));
                  desc7.putObject( charIDToTypeID('Usng'), stringIDToTypeID('SaveForWeb'), desc8 );
                  executeAction( charIDToTypeID('Expr'), desc7, DialogModes.NO );
              };
              }
              main()
              
              • 4. Re: Batch save to multiple folders
                Muppet Mark-QAl63s Level 4

                Paul, I can't take at look at your dialogs but do they look like something you'd frame some 18th century painting in?

                frame.jpg

                Just my mental picture…

                • 5. Re: Batch save to multiple folders
                  Paul Riggott Level 6

                  Thanks Mark, all I've done is rip apart and modified that last Bridge processor so it didn't take too long to do.

                  • 6. Re: Batch save to multiple folders
                    Muppet Mark-QAl63s Level 4

                    I was thinking I might get to see one at a digital exhibition @ the tate modern… I just don't know where some of you's find the time? I seem to spend forever looking at docs and now it looks like i've not progressed past the "Hello World" sample!!!

                    • 7. Re: Batch save to multiple folders
                      Janice Welton Level 1

                      WOW!!

                      You're a genius! This works amazingly!!

                       

                      Thanks!

                      Janice

                      • 8. Re: Batch save to multiple folders
                        akribie Level 2

                        I know this is a very old thread, but I wonder if anyone is clever enough to modify the script (Paul Riggott 30-May-2010 14:16 (in response to Janice Welton)) so that one can specify the toplevel input folder (as now) and also a toplevel output folder. At present the script works great but saves output to the source folder, which is not what I wish to do.

                         

                        Thanks for any help.

                        • 9. Re: Batch save to multiple folders
                          SuperMerlin Level 5

                          His latest version is on github "Picture Processor" that might work for you?

                          https://raw.githubusercontent.com/Paul-Riggott/PS-Scripts/master/Picture%20Processor.jsx

                          Just right click on the page and select "Save Page As"

                          • 10. Re: Batch save to multiple folders
                            Stephen_A_Marsh Adobe Community Professional

                            I’d give Image Processor Pro from xbytor a try (installation instructions can be found in the .zip download, I’d ignore the .zxp versions):

                             

                            ImageProcessorPro-3_2b5.zip

                             

                            ps-scripts - Browse /Image Processor Pro/v3_2 betas at SourceForge.net

                             

                            ipp.png

                             

                            Even though this is a Photoshop script (File > Automate > Image Processor Pro), it can accept selected files in Bridge as input.

                             

                            The options to save to a named subfolder created on the fly and to keep the same folder structure/names as the input are worth exploring.

                            • 11. Re: Batch save to multiple folders
                              akribie Level 2

                              Thanks for the nudge.  I've been using Image Processor Pro for years, but always from Bridge from where it will not process a selection of folders. I didn't dig deep enough before looking for an alternative for my batch task.

                              Now you've given me the hint, I find that setting up the source and target manually in the script dialogue does exactly what I want, so very many thanks. Takes a source top level folder and outputs to target folder whilst maintaining folder structure once the options have been correctly set up.

                              Problem solved.