Highlighted

Photoshop javascript: Open files in all subfolders

New Here ,
Jul 02, 2013

Copy link to clipboard

Copied

Hi guys

I'm very new to javascript, and general Photoshop scripting. My script is coming on well, but I struggle working with files and folders. It's a lack of basic javascript knowledge, which I need to work on. Right now, I'm trying to expand the image open part of my script, so that it opens images regardless of whether they are in a subfolder or not.

You can see my input folder (C:/Input). I want to be able to throw files in there, some in folders, some not. Out of interest, my outputs will be combined into one output folder... that bit is fine.

var inFolder = new Folder("C:/Input")

if(inFolder != null){

var fileList = inFolder.getFiles(/\.(jpg|tif|psd|bmp|gif|png|)$/i);

}

for(var a = 0 ;a < fileList.length; a++)

{

var docRef = open(fileList);

//do things here

}

Is there an easy way of expanding this to include files in subfolders? All advice greatly appreciated.

Thanks

David

You could combine the code you posted with the code I posted like this:

var topFolder = new Folder('~/desktop/test');
var fileandfolderAr = scanSubFolders(topFolder,/\.(jpg|tif|psd|bmp|gif|png|)$/i);

var fileList = fileandfolderAr[0];

for(var a = 0 ;a < fileList.length; a++)

{

var docRef = open(fileList);

//do things here

}

function scanSubFolders(tFolder, mask) { // folder object, RegExp or string
    var sFolders = new Array();
    var allFiles = new Array();
    sFolders[0] = tFolder;
    for (var j = 0; j < sFolders.length; j++){ // loop through folders            
        var procFiles = sFolders.getFiles();
        for (var i=0;i<procFiles.length;i++){ // loop through this folder contents
            if (procFiles instanceof File ){
                if(mask==undefined) allFiles.push(procFiles);// if no search mask collect all files
                if (procFiles.fullName.search(mask) != -1) allFiles.push(procFiles); // otherwise only those that match mask
        }else if (procFiles instanceof Folder){
            sFolders.push(procFiles);// store the subfolder
            scanSubFolders(procFiles, mask);// search the subfolder
         }
      }
   }
   return [allFiles,sFolders];
};

Topics

Actions and scripting

Views

24.7K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Photoshop javascript: Open files in all subfolders

New Here ,
Jul 02, 2013

Copy link to clipboard

Copied

Hi guys

I'm very new to javascript, and general Photoshop scripting. My script is coming on well, but I struggle working with files and folders. It's a lack of basic javascript knowledge, which I need to work on. Right now, I'm trying to expand the image open part of my script, so that it opens images regardless of whether they are in a subfolder or not.

You can see my input folder (C:/Input). I want to be able to throw files in there, some in folders, some not. Out of interest, my outputs will be combined into one output folder... that bit is fine.

var inFolder = new Folder("C:/Input")

if(inFolder != null){

var fileList = inFolder.getFiles(/\.(jpg|tif|psd|bmp|gif|png|)$/i);

}

for(var a = 0 ;a < fileList.length; a++)

{

var docRef = open(fileList);

//do things here

}

Is there an easy way of expanding this to include files in subfolders? All advice greatly appreciated.

Thanks

David

You could combine the code you posted with the code I posted like this:

var topFolder = new Folder('~/desktop/test');
var fileandfolderAr = scanSubFolders(topFolder,/\.(jpg|tif|psd|bmp|gif|png|)$/i);

var fileList = fileandfolderAr[0];

for(var a = 0 ;a < fileList.length; a++)

{

var docRef = open(fileList);

//do things here

}

function scanSubFolders(tFolder, mask) { // folder object, RegExp or string
    var sFolders = new Array();
    var allFiles = new Array();
    sFolders[0] = tFolder;
    for (var j = 0; j < sFolders.length; j++){ // loop through folders            
        var procFiles = sFolders.getFiles();
        for (var i=0;i<procFiles.length;i++){ // loop through this folder contents
            if (procFiles instanceof File ){
                if(mask==undefined) allFiles.push(procFiles);// if no search mask collect all files
                if (procFiles.fullName.search(mask) != -1) allFiles.push(procFiles); // otherwise only those that match mask
        }else if (procFiles instanceof Folder){
            sFolders.push(procFiles);// store the subfolder
            scanSubFolders(procFiles, mask);// search the subfolder
         }
      }
   }
   return [allFiles,sFolders];
};

Topics

Actions and scripting

Views

24.7K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Guru ,
Jul 02, 2013

Copy link to clipboard

Copied

Folder.getFiles() only works with one folder at a time. To get all the files in the folder as well as in subfolders you need to scan each subfolder. One way to do that is with a recursive function. Something like this:

var topFolder = new Folder('~/desktop/test');

var fileandfolderAr = scanSubFolders(topFolder,/\.(jpg|tif|psd|bmp|gif|png|)$/i);

alert('Scan of ' + topFolder.fullName + '\n' + fileandfolderAr[0].length + ' files\nLast File: ' + decodeURI(fileandfolderAr[0][fileandfolderAr[0].length-1]));

alert('Scan of ' + topFolder.fullName + '\n' + fileandfolderAr[1].length + ' folders\nLast Folder: ' + decodeURI(fileandfolderAr[1][fileandfolderAr[1].length-1]));

function scanSubFolders(tFolder, mask) { // folder object, RegExp or string

    var sFolders = new Array();

    var allFiles = new Array();

    sFolders[0] = tFolder;

    for (var j = 0; j < sFolders.length; j++){ // loop through folders            

        var procFiles = sFolders.getFiles();

        for (var i=0;i<procFiles.length;i++){ // loop through this folder contents

            if (procFiles instanceof File ){

                if(mask==undefined) allFiles.push(procFiles);// if no search mask collect all files

                if (procFiles.fullName.search(mask) != -1) allFiles.push(procFiles); // otherwise only those that match mask

        }else if (procFiles instanceof Folder){

            sFolders.push(procFiles);// store the subfolder

            scanSubFolders(procFiles, mask);// search the subfolder

         }

      }

   }

   return [allFiles,sFolders];

};

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Community Beginner ,
Sep 11, 2020

Copy link to clipboard

Copied

this is an excellent answer but you forgot to put the index numbers in in Files within the loop... it should look like in the code below.

 

 

function traverseFolder(path) {

// Create new folder object based on path string
var folder = new Folder(path);

// Get all files in the current folder
var files = folder.getFiles();

// Loop over the files in the files object
for (var i = 0; i < files.length; i++) {

// Check if the file is an instance of a file
// else call the traverse folder recursively with the current folder as an argument

if (files[i] instanceof File) {

// Convert the file object to a string for matching purposes (match only works on String objects)
var fileString = String(files[i]);
// Check if the file contains the right extension

if (fileString.match(/.(html)$/)) {

// Do something if the file matches
$.writeln(fileString + ' : This is a html file' + "\n");

} else {

// Do something if the file doesn't match
$.writeln(fileString + ' : This is NOT an html file' + "\n");

}

} else {
$.writeln('passing folder: ' + files[i] + "\n");

// Call method recursively with the current folder as an argument
traverseFolder(files[i]);
}

}

}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Community Beginner ,
Jul 02, 2013

Copy link to clipboard

Copied

var traverseFolder = function(path)

{

     // Create new folder object based on path string

     var folder = new Folder(path);

     // Get all files in the current folder

     var files = folder.getFiles();

     // Loop over the files in the files object

     for (var i = 0; i &lt; files.length; i++)

     {

          // Check if the file is an instance of a file

          // else call the traverse folder recursively with the current folder as an argument

          if (files instanceof File)

          {

               // Convert the file object to a string for matching purposes (match only works on String objects)

               var fileString = String(files);

               // Check if the file contains the right extension

               if (fileString.match(/.(jpg|tif|psd|bmp|gif|png)$/))

               {

                    // Do something if the file matches

                    alert(fileString + 'good file');

               }

               else

               {

                    // Do something if the file doesn't match

                    alert(fileString + 'bad file');

               }

          }

          else

          {

               alert('passing folder: ' + files);

               // Call method recursively with the current folder as an argument

               traverseFolder(files);

          }

     }

}

traverseFolder('c:/path');

You can use the traverseFolder() function and pass the path as a parameter. Make sure to delete the alerts, there just there to show you which folder/file is currently being loaded. Also make sure to delete the comments in the for statement, since they cause the program to slow down unneccesarily.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Guru ,
Jul 02, 2013

Copy link to clipboard

Copied

Pascalculator wrote:

... make sure to delete the comments in the for statement, since they cause the program to slow down unneccesarily.

The comments will not effect the speed of the script as it runs. If the comments help you remember what the script does, how it does what it does, or how to use it I suggest leaving them in.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jul 03, 2013

Copy link to clipboard

Copied

Thank you Michael and Pascalculator for your explanations, I'm very grateful. I've struggled a little to integrate either into my script - I will close myself in a dark room later and work on it. I'll get back when I've figured it!

Thanks

David

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Guru ,
Jul 03, 2013

Copy link to clipboard

Copied

You could combine the code you posted with the code I posted like this:

var topFolder = new Folder('~/desktop/test');
var fileandfolderAr = scanSubFolders(topFolder,/\.(jpg|tif|psd|bmp|gif|png|)$/i);

var fileList = fileandfolderAr[0];

for(var a = 0 ;a < fileList.length; a++)

{

var docRef = open(fileList);

//do things here

}

function scanSubFolders(tFolder, mask) { // folder object, RegExp or string
    var sFolders = new Array();
    var allFiles = new Array();
    sFolders[0] = tFolder;
    for (var j = 0; j < sFolders.length; j++){ // loop through folders            
        var procFiles = sFolders.getFiles();
        for (var i=0;i<procFiles.length;i++){ // loop through this folder contents
            if (procFiles instanceof File ){
                if(mask==undefined) allFiles.push(procFiles);// if no search mask collect all files
                if (procFiles.fullName.search(mask) != -1) allFiles.push(procFiles); // otherwise only those that match mask
        }else if (procFiles instanceof Folder){
            sFolders.push(procFiles);// store the subfolder
            scanSubFolders(procFiles, mask);// search the subfolder
         }
      }
   }
   return [allFiles,sFolders];
};

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jul 03, 2013

Copy link to clipboard

Copied

Thanks so much, Micheal, for all your help. It's working fantastically, I really appreciate all your input, and to Pascalculator. Will try to pay back the community. : )

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Apr 04, 2014

Copy link to clipboard

Copied

Hello,

Inspired by the topic created a script that converts files .eps to .jpg. However, I have a problem. The script correctly reads the folders and subfolders and contained in their files and saves the converted files to the input folder.

I do not know how to save the converted file ".jpg" to the folder from which it was read source file.

Please suggestions on how to solve this problem.

My script looks like this:

function saveJPEG( doc, saveFile, qty ) {

   var saveOptions = new JPEGSaveOptions( );

   saveOptions.embedColorProfile = true;

   saveOptions.formatOptions = FormatOptions.STANDARDBASELINE;

   saveOptions.matte = MatteType.NONE;

   saveOptions.quality = qty;

   doc.saveAs( saveFile, saveOptions, true );

};

function scanSubFolders(tFolder, mask) { // folder object, RegExp or string

    var sFolders = new Array();

    var allFiles = new Array();

    sFolders[0] = tFolder;

    for (var j = 0; j < sFolders.length; j++){ // loop through folders           

        var procFiles = sFolders.getFiles();

        for (var i=0;i<procFiles.length;i++){ // loop through this folder contents

            if (procFiles instanceof File ){

                if(mask==undefined) allFiles.push(procFiles);// if no search mask collect all files

                if (procFiles.fullName.search(mask) != -1) allFiles.push(procFiles); // otherwise only those that match mask

        }else if (procFiles instanceof Folder){

            sFolders.push(procFiles);// store the subfolder

            scanSubFolders(procFiles, mask);// search the subfolder

         }

      }

   }

   return [allFiles,sFolders];

};

function fitImage( xUnitValue, yUnitValue ){

var fitImage = stringIDToTypeID( "3caa3434-cb67-11d1-bc43-0060b0a13dc4" );

    var size = new ActionDescriptor();

    size.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Pxl" ), xUnitValue.as( 'px' ) );

    size.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Pxl" ), yUnitValue.as( 'px' ) );

executeAction( fitImage, size, DialogModes.NO );

};

var openOptions = new EPSOpenOptions();

openOptions.antiAlias = true;

openOptions.constrainProportions = true;

openOptions.mode = OpenDocumentMode.RGB;

openOptions.resolution = 600

var x = new UnitValue( 1280, 'px' );

var y = new UnitValue( 1024, 'px' );

var inputFolder = Folder.selectDialog (prompt);

var outputFolder = inputFolder;

var fileandfolderAr = scanSubFolders(inputFolder,/\.(eps|)$/i);

var fileList = fileandfolderAr[0];

for(  var i =0; i < fileList.length; i++ ) {

   var doc = open( fileList[ i ], openOptions );      var docName = decodeURI ( doc.name );

   docName = docName.match( /(.*)(\.[^\.]+)/ ) ? docName = docName.match( /(.*)(\.[^\.]+)/ ) : docName = [ docName, docName, undefined ];

   var saveName = docName[ 0 ]; // strip the extension

   var saveFile =  new File ( outputFolder + '/' + saveName + '.jpg' );

       doc.resizeImage( undefined, undefined, 72, ResampleMethod.NONE );

   doc.flatten( );

   doc.convertProfile( 'sRGB IEC61966-2.1', Intent.RELATIVECOLORIMETRIC, true, true );

   fitImage( x, y );

   saveJPEG( doc, saveFile, 8 );// or

   //exportSFW( doc, saveFile, 65 );

   doc.close( SaveOptions.DONOTSAVECHANGES );

}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Adobe Community Professional ,
Jul 31, 2016

Copy link to clipboard

Copied

In the last part of code in linecode:

var saveFile =  new File ( outputFolder + '/' + saveName + '.jpg' );

replace outputFolder with activeDocument.path, so you'll get:

var saveFile =  new File ( activeDocument.path + '/' + saveName + '.jpg' );

I hope it will work, because I had to do two other little changes:

  • I deleted EPS options from var doc = open( fileList[ i ], openOptions ); as I had no EPS files and were opening JPG's
  • in fitImage function I had to change in 2 following lines xUnitValue.as('px') for xUnitValue and yUnitValue.as('px') for yxUnitValue (maybe because I tested it in CS2 that second change was necessary)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Jul 31, 2016

Copy link to clipboard

Copied

Kukurykus wrote:

replace outputFolder with activeDocument.path, so you'll get:

  1. varsaveFile=newFile(activeDocument.path+'/'+saveName+'.jpg');

That will only work for old documents when the  Active document has been save in the past then there is a backing file and path.  It will not work for new Photoshop documents there is no activeDocument.path or backing file.

JJMack

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Adobe Community Professional ,
Jul 31, 2016

Copy link to clipboard

Copied

That's true, but there is backing file so the path as there are EpsOpenOptions and  Folder.selectDialog (prompt)  in the code. But that had to be a tip just in case I guess

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Sep 28, 2019

Copy link to clipboard

Copied

Error 4: sFolders.getFiles is not a function.

Line 21

var procFiles = sFolders.getFiles();

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...