The Process_Folder
template in Fiji is a wonderful thing. It’s the starting point of most of the ImageJ macros that we use in the lab. However, it has a problem. This post is about how to fix it.
tl;dr use this gist instead of the built-in template.
The Process_Folder
template
If you’re reading this, you probably know that the Process_Folder.ijm
template is great. Given an input directory, it will parse it (and any subdirectories) and find all files with a given extension. These files are each passed to a function. The beauty is that this function can contain any routine that you’d like to perform on each image. So usually, it’s just a case of pasting in your code and away you go.

The template is accessed like this, from within Fiji.

…and this is the template.
So what’s the problem?
The code is written to recurse through subdirectories. However, this is not coded correctly in the template. This leads to two problems which are seriously confusing for beginning coders (who are most likely to use the template) and baffling for experienced coders.
Consider this directory tree:

We have a directory with one tif, and a subdirectory called top. This subdirectory has two tiffs (a and b) and a subdirectory called mid and so on.
If we run the built-in template and select the parent directory as the input, and for argument’s sake as the output (this doesn’t affect anything), we get the following result.

There’s two problems with this output:
- double slashes in the file path – see, for example between
top
andmid
. - the template requires
File.separator
to open a file, BUT only if it is in the parent directory – note howfile_in_parent_directory.tif
has a single slash between it and its parent directory but every instance ofa.tif
is preceded by a double slash. Confusing!
Because double slashes don’t break anything. The rational way to deal with these problems is to ignore 1, and solve 2 by just including open(input + File.separator + file);
in the processFile()
function so that files can be processed if they are in the parent folder or a subfolder. Folks learning to code, usually face the problem of their script only processing certain files because they fail to include this hack.
The double slashes in the file path don’t break anything but they are seriously annoying. Firstly, it’s a problem to do string replacement if you can’t anticipate whether there will be one slash or two. Secondly, if you’d like to save the file paths as a text file to parse later in R during your analysis, the double slashes are a headache. For example, separating the folders and subfolder names and file names is unnecessarily complicated.
It seems this issue was discussed when the template was changed to include Script Parameters, but the thread indicates they didn’t have the correct fix in mind.
The solution
Here’s a modified form that is more simple to use:

The code is below or you can access it here.
We solve the problem of erroneously adding the double slashes to the directory path by simply checking if the path terminates in a separator or not. If not, a separator gets added. This means we can get rid of the hacky part of the original template where the File.separator
gets added to the path, even if one is already there. Now, this fix means that the path to the directory containing the file we want to process terminates in a single slash, so now we don’t need the open(input + File.separator + file);
in the processFile()
function and can simply start our code with open(input + file);
in the processFile()
function.
Happy coding!
/*
* Macro template to process multiple images in a folder
*/
#@ File (label = "Input directory", style = "directory") input
#@ File (label = "Output directory", style = "directory") output
#@ String (label = "File suffix", value = ".tif") suffix
// See also Process_Folder.py for a version of this code
// in the Python scripting language.
processFolder(input);
// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
if(endsWith(input, "/")) input = substring(input, 0, (lengthOf(input)-1));
if(!endsWith(input, "/") | !endsWith(input,"\\")) input = input + File.separator;
list = getFileList(input);
list = Array.sort(list);
for (i = 0; i < list.length; i++) {
if(File.isDirectory(input + list[i]))
processFolder(input + list[i]);
if(endsWith(list[i], suffix))
processFile(input, output, list[i]);
}
}
function processFile(input, output, file) {
// Do the processing here by adding your own code.
// Leave the print statements until things work, then remove them.
print("Processing: " + input + file);
print("Saving to: " + output);
}
Edit 2025-02-17: updated gist so that the solution also works on Windows
—
This post is part of a series of tips.