Process.ijm with ImageCalculator not from the same image



Is it possible to open 2 directories (or subfolders) within process.ijm and apply ImageCalculator to a files in dir1 and their matching partner in dir2?

I’ve tried placing all my files in the same directory and calling each red1 and mask1, to red126 and mask 126 and using this code I found online… but it just keeps failing at the first “if”, unable to locate the files…

// lets you choose your folder
inputDir = getDirectory("Choose your input folder");

// makes a sub directory into your chosen folder
outputDir = inputDir + "results\\";

if(!File.exists(outputDir)) File.makeDirectory(outputDir);

max = getNumber("How many images do you expect?",126);
// lets you choose the naming of your files
redName = getString("Whats the prefix of your first images?","red");
maskName = getString("Whats the prefix of your second images?","mask");
// a loop through your images... (1 ... max)
for(i=1; i<=max; i++){
red = inputDir + redName + i;
mask = inputDir + maskName + i;
// only proceeds if both files are there
if(File.exists(red) && File.exists(mask)){
// opens the images and gives them the temporary names "red" and "mask"
// the next lines do your procedure
imageCalculator("Transparent-zero create","red","mask");
// saves the image into the sub directory as: overlay1..max
saveAs("tiff", outputDir + "overlay" + i);
// closes all images before the next iteration
while(nImages > 0) close();
} else print("At least one file was missing! (" + redName + i + " or " + maskName + i + " )");




put “print()” statements in your code and check every step for the desired paths strings or numbers

And please study the docs, especially:

I’m sure you will fix the problem yourself.




Hi there
Thank you for your help.
I have read the docs and appreciate that these forums are not for instant answers and that’s not how one learns anyway.
Could you perhaps advise as to the following as it is a bottleneck to progression, hence why I was resorting to googling other people’s scripts. I prefer to go with my own from scratch.

Basic Q - if you want to perform an operation in a batch fashion in which there are 2 files at a time which are not derived from the same image…what is the best approach to take? Same directory or multiple directory with file name strategy? - and either way I would be hugely appreciative if you could provide an example of a sample to call the string correctly.

Ie a very simple problem but am going down all sorts of false alleyways:

I have a set of images, say A1-A200
and a set of images, say B1-B200
In batch, I want to have A1 and B1 utilised in the ImageCalculator function. Then A2 and B2 and so on.
Any hints as to approach?

Many thanks



I think you should be able to call/set two input directories… The best would be to read up on Script Parameters - they will make your life so much easier in the long run!

example - use this code at the top of your scripts:

#@File(label = "Input directory", style = "directory") input1
#@File(label = "Input directory", style = "directory") input2
#@File(label = "Output directory", style = "directory") output

You can then work with the images from each directory as you need…

Here are some other super helpful links for scripting in ImageJ:

Read up a bit… test somethings out on your own and come back when you have more questions. We are here to help!

eta :slight_smile:

TOO - here is a quick script I put together to run through two directories as a quick-and-dirty example (you will need to edit things as you need for your specific case):

#@File(label = "Input directory", style = "directory") input1
#@File(label = "Input directory", style = "directory") input2
#@File(label = "Output directory", style = "directory") output
#@ String (label = "File suffix", value = ".tif") suffix

processFolder(input1, input2);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input1, input2) {
	list1 = getFileList(input1);
	list1 = Array.sort(list1);
	list2 = getFileList(input2);
	list2 = Array.sort(list2);
	if (list1.length == list2.length) {
		for (i = 0; i < list1.length; i++) {
			if(File.isDirectory(input1 + File.separator + list1[i]) && File.isDirectory(input2 + File.separator + list2[i]))
				processFolder(input1 + File.separator + list1[i], input1 + File.separator + list1[i]);
			if((endsWith(list1[i], suffix)) && (endsWith(list2[i], suffix)))
				processFile(input1, input2, output, list1[i], list2[i]);
	} else {
	print("The two directories do not have the same # of files!");

function processFile(input1, input2, output, file1, file2) {
	// Do the processing here by adding your own code.
	// Leave the print statements until things work, then remove them.
	print("Processing: " + input1 + File.separator + file1);
	print("Processing: " + input2 + File.separator + file2);
	print("Saving to: " + output);


Thanks, this is super helpful.

When I print the inputs and files, they are called just fine - but when I attempt to open to process I get the error "the specified file … … .tif does not exist"
Any idea?


function processFile(input1, input2, output, file1, file2) {
// Do the processing here by adding your own code.
// Leave the print statements until things work, then remove them.


run("Bio-Formats", "open=[" + input1 + "/" + file1 + " ]");
run("Bio-Formats", "open=[" + input2 + "/" + file2 + " ]");

imageCalculator("Transparent-zero create", "file1","file2");


Good day,

not sure what this macro is intended to do but do you need “Bio-Formats”? Which kind of image files do you want to open?



appears twice, and why do you call






Hi Herbie,
I have edited that print, apologies.
I only used Bioformats because when I used (open) I was getting the error “File is not in a supported format, a reader or plugin is not available, or was not found”.

The files definitely exist and are simply 8 bit tifs.

Oh, apologies, I thought this was required in batch mode based on the script slide

but I guess this is not needed - even if I delete this the same error appears.

Also - the macro is supposed to use the transparent-zero function of ImageCalculator on an image and its partner from 2 differently processed channels of an original image. There are multiple images analysed, hence the process script. These channels are saved in different folders.


Well Dear,

why do you use inverted commas for the file names?




Here is a test macro:

// this part creates two test images in new folders in your home directory
homeDir = getDirectory( "home" );
dir1 = homeDir + "dirOne/";
dir2 = homeDir + "dirTwo/";
dirResult = homeDir + "dirResult/";
File.makeDirectory( dir1 );
File.makeDirectory( dir2 );
File.makeDirectory( dirResult );
fileName1 = "MyImage-1.tif";
fileName2 = "MyImage-2.tif";
newImage( fileName1, "8-bit ramp", 256, 256, 1 );
saveAs( "Tiff", dir1 + fileName1 );
run( "Duplicate...", " " );
run( "Rotate 90 Degrees Right" );
saveAs( "Tiff", dir2 + fileName2 );
// this part opens both files and processes them
setBatchMode( true ); 
openAndProcess( dir1, dir2, dirResult, fileName1, fileName2 );
setBatchMode( false ); 
function openAndProcess( input1, input2, output, file1, file2 ) {
	open( input1 + file1 );
	open( input2 + file2 );
	imageCalculator( "Difference create", file1, file2 );
	saveAs( "Tiff", output + "Result.tif" );

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

If this macro does what it is intended to do (check the files and directories in your home directory after running it), then you can debug and adapt your macor accordingly.

And yes, please carefully check the syntax of your macro!





You just have an extra space before the right bracket that needs to go… then it will work just fine.

	run("Bio-Formats", "open=[" + input1 + "/" + file1 + "]");
	run("Bio-Formats", "open=[" + input2 + "/" + file2 + "]");

Too - we do recommend users opening their files using Bio-Formats … to be sure the metadata is read in correctly, etc. This is especially true for .tif files - see this page.

eta :slight_smile:


Hi eta,

Thanks so much for your help. I thought this was working fine but whilst checking everything step by step as I had a few strange output values I realised that the initial processing step (the image calculator step) is not working how I would imagine when I do it manually… here is the output of the macro recorder for one file, followed by the script. Any ideas?

recorder output:
imageCalculator(“Transparent-zero create”, “redfile.tif”,“maskfile.tif”);
selectWindow(“Result of redfile.tif”);

run(“Bio-Formats”, “open=[” + input1 + “/” + file1 + “]”);
run(“Bio-Formats”, “open=[” + input2 + “/” + file2 + “]”);

imageCalculator(“Transparent-zero create”, file1 , file2 );
saveAs(“Tiff”, output+list1[i]);


saveAs(“Tiff”, output+list1[i]);

requires a loop index variable i, that doesn’t show up in your code.




Hi Herbie,
Thanks - but even if I manually save the output the output is incorrect. (e.g. just
saveAs(“Tiff") so I think something is incorrect before then?



incorrect in which sense?
are there some errors?


Well Emily,

adding the following code lines

selectImage( file1 );
selectImage( file2 );


imageCalculator(“Transparent-zero create”, file1, file2 );

may help. And please make sure that no other images are open in ImageJ when you start the macro.




Hi thanks for your help.
This sounds stupid but it seems like its actually adding a negative version of one input rather than Transparent zero.

I stripped back files and my macro so that input1 and input2 contain exactly the correct files to perform the image calculator function.

input1 contains files which are 8 bit, black to “red” - some messy image with lots going on.
input2 contains files which are 8 bit masks, inverted already so they have a black background with some white irregular-shaped-dots which are of interest to analyse in input1

I apply imageCalculator transparent-zero manually and I achieve my expected “red” background with my irregular shaped dots containing varying “grey” pixel value signals of interest.

However as macro, it seems to have the same effect as taking file2, inverting it, and adding it to file1. (even on the first file)


I feel like I’m being super stupid here, but I can’t work out why. I’ve changed directory file names to make sure they’re non-identical…

input appreciated!
Thanks again


Good day Emily,

please post your two input images and the correct result image as PNG-files to the Forum, so we can investigate the problem more systematically.




Thanks - below are the images and manual output…

from input1

![mask file2|499x499]

from input2

expected output


Thanks for the images Emily!

As far as I see, the solution of your problem is to invert the mask (input2) after it has be opened:

run( “Bio-Formats”, “open=[” + input1 + “/” + file1 + “]” );
run( “Bio-Formats”, “open=[” + input2 + “/” + file2 + “]” );
run( "Invert" );
imageCalculator( “Transparent-zero create”, file1, file2 );




Oh! Thank you! (I thought I had tried that already …!)
But that is a strange quirk!

Thanks again!