ImageJ Macro Language

Introduction

A macro is a simple program that automates a series of ImageJ commands. The easiest way to create a macro is to record a series of commands using the command recorder. A macro is saved as a text file and executed by selecting a menu command, by pressing a key or by clicking with the mouse.

There are more than 200 example macros on the ImageJ Web site. To try one, open it in a browser window, copy it to the clipboard (crtl-a, ctrl-c), switch to ImageJ, open an editor window (ctrl-shift-n), paste (ctrl-v), then run it using the editor's File/Run Macro command (ctrl-r). Most of the example macros are also available in the macros folder, inside the ImageJ folder.

"Hello World" Example

As an example, we will create, run and install a one line Hello World macro. First open an editor window using Plugins/New (shift-n). In the dialog box, enter "Hello_World" as the Name, select "Macro" as the Type, then click "OK". (The underscore in the name is how ImageJ decides, when it is starting up, which ".txt" files in the plugins folder are to be installed as macros.)

[Dialog]

In the editor window, enter the following line:

print("Hello world");
To test the macro, use the editor's File/Run Macro command (ctrl-R or cmd-R). To save it, use the editor's File/Save As command. The macro will be automatically installed as a "Hello World" command in the Plugins menu when you restart ImageJ, assuming the file name has an underscore in it and the macro was saved in the plugins folder or a subfolder. You can run this macro by pressing a single key by creating a shortcut using Plugins/Shortcuts/Create Shortcut.

To re-open a macro, use the File/Open or Plugins/Edit commands, or drag and drop it on the "ImageJ" window (Windows) on the the ImageJ icon (Mac).

204 more Hello World programs are available on the ACM Hello World! Web site.

Using the Command Recorder to Generating Macros

Simple macros can be generated using the command recorder (Plugins/Macros/Record). For example, this macro, which measures and labels a selection,
run("Measure");
run("Label");
is generated when you use the Analyze/Measure and Analyze/Label commands with the recorder running. Save this macro in the plugins folder, or a subfolder, as "Measure_And_Label.txt", restart ImageJ and there will be a new "Measure And Label" command in the Plugins menu. Use the Plugins/Shortcuts/Create Shortcut command to assign this new command a keyboard shortcut.

[Dialog]

In this example, the "Measure And Label" macro is assigned to the F1 key. Note how the underscores in the macro file name (at least one is required) are converted to spaces in the command name.

Macro Sets

A macro file can contain more than one macro, with each macro declared using the macro keyword.
    macro "Macro 1" {
        print("This is Macro 1");
    }

    macro "Macro 2" {
        print("This is Macro 2");
    }
In this example, two macros, "Macro 1" and "Macro 2", are defined. To test these macros, select them, Copy (ctrl-c), switch to ImageJ, open an editor window (ctrl-shift-n), Paste (ctrl-v), select the editor's Macro/Install Macros command, then select Macros/Macro 1 to run the first macro or Macros/Macros 2 to run the second.

Macros in a macro set can communicate with each other using global variables.

    var s = "a string";

    macro "Enter String..." {
        s = getString("Enter a String:", s);
    }

    macro "Print String" {
        print("This is Macro 2");
    }
Use the editor's File/Save As command to create a macro file containing these two macros. Name it something like "MyMacros.txt" and save it in the macros folder inside the ImageJ folder. (Note that the ".txt extension is required.) Then, to install the macros in the Plugins/Macros/ submenu, use the Plugins/Macros/Install command and select "MyMacros.txt" in the file open dialog. Change the name to "StartupMacros.txt" and ImageJ will automatically install the macros when it starts up.

Keyboard Shortcuts

A macro in a macro set can be assigned a keyboard shortcut by listing the shortcut in brackets after the macro name.
    macro "Macro 1 [a]" {
        print("The user pressed 'a'");
    }

    macro "Macro 2 [1]" {
        print("The user pressed '1'");
    }
In this example, pressing 'a' runs the first macro and pressing '1' runs the second. These shortcuts duplicate the shortcuts for Edit/Selection/Select All and Analyze/Gels/Select First Lane so you now have to hold down control (command on the Mac) to use the keyboard shortcuts for these commands.

Note that keyboard shortcuts will not work unless the macros are installed and the "ImageJ" window, or an image window, is the active (front) window and has keyboard focus. You install macros using the macro editor's Macros/Install Macros command or the Plugins/Macros/Install command. Install the two macros in the above example and you will see that the commands

    Macro 1 [a]
    Macro 2 [1]
get added to Plugins/Macros submenu. Save these macros in a file named "StartupMacros.txt" in the macros folder and ImageJ will automatically install them when it starts up.

Function keys ([f1], [f2]...[f12]) and numeric keypad keys ([n0], [n1]..[n9], [n/], [n*], [n-], [n+] or [n.]) can also be used for shortcuts. ImageJ will display an error message if a function key shortcut duplicates a shortcut used by a plugin. Numeric keypad shortcuts (available in ImageJ 1.33g or later) are only used by macros so duplicates are not possible. Note that on PCs, numeric keypad shortcuts only work when the Num Lock light is on. A more extensive example (KeyboardShortcuts) is available.

Tool Macros

You can define macros that are are added to the ImageJ tool bar and executed when the user selects the tool and clicks on the image. Here is an example tool that displays the mouse click coordinates:
    macro "Sample Tool - C0a0L18f8L818f" {
       getCursorLoc(x, y, z, flags);
       print("Sample: "+x+" "+y);
    }
To install this tool, open an editor window (Plugins/New), paste in the macro, then use the editor's Macros/Install Macros command. Put this macro in a file named "StartupMacros.txt" in the macros folder and it will automatically be installed when ImageJ starts up. A macro file can contain up to six tool macros and any number of non-tool macros. Macro files must have a ".txt" extension. The cryptic hex code at the end of the macro name, which defines the tool icon, is described below.

A tool can display a configuration dialog box when the user double clicks on it. To set this up, add a macro that has the same name as the tool, but with " Options" added, and that macro will be called each time the user double clicks on the tool icon. In this example, the getNumber dialog is displayed when the users double clicks on the circle tool icon.

    var radius = 20;

    macro "Circle Tool - C00cO11cc" {
       getCursorLoc(x, y, z, flags);
       makeOval(x-radius, y-radius, radius*2, radius*2);
    }

    macro "Circle Tool Options" {
       radius = getNumber("Radius: ", radius);
    }
Tool macros with names ending in "Action Tool" perform an action when you click on their icon in the tool bar. In this example, the "About ImageJ" window is displayed when the user clicks on the tool icon (a question mark).
    macro "About ImageJ Action Tool - C059T3e16?" {
       requires("1.37t");
       run("About ImageJ...");
    }
More examples are available at rsb.info.nih.gov/ij/macros/tools/ or in the ImageJ/macros/tools folder. Use File/Open (or drag and drop) to open one of these files and the tools defined in it will be automatically installed, or use the Plugins/Macros/Install command to install tools without opening an editor window.

Tool macro icons are defined using a simple and compact instruction set consisting of a one letter commands followed by two or more lower case hex digits.

Command Description
Crgb set color
Bxy set base location (default is (0,0))
Rxywh draw rectangle
Fxywh draw filled rectangle
Oxywh draw oval
oxywh draw filled oval
Lxyxy draw line
Dxy draw dot (1.32g or later)
Pxyxy...xy0 draw polyline
Txyssc draw character
Where x (x coordinate), y (y coodinate), w (width), h (height), r (red), g (green) and b (blue) are lower case hex digits that specify a values in the range 0-15. When drawing a character (T), ss is the decimal font size in points (e.g., 14) and c is an ASCII character.

Variables

The ImageJ macro language is "typeless". Variables do not need to be declared and do not have explicit data types. They are automatically initialized when used in an assignment statement. A variable can contain a number, a string or an array. In fact, the same variable can be any of these at different times.

In the following example, a number, a string and an array are assigned to the same variable.

    v = 1.23;
    print(v);
    v = "a string";
    print(v);
    v = newArray(10, 20, 50);
    for (i=0; i<v.length; i++) print(v[i]);
You can run this code by selecting it, copying it to the clipboard (ctrl-C), switching to ImageJ, opening an editor window (Edit/New), pasting (ctrl-V), then pressing ctrl-R. (Note: on the Mac, use the apple key instead of the control key.)

Global variables should be declared before the macros that use them using the 'var' statement. For example:

    var x=1;
    
    macro "Macro1..." {
        x = getNumber("x:", x);
    }
    
    macro "Macro2" {
        print("x="+x);
    }
Note that variable names are case-sensitive. "Name" and "name" are different variables.

Operators

The ImageJ macro language supports almost all of the standard Java operators but with fewer precendence levels.
Operator Prec. Description
++ 1 pre or post increment
-- 1 pre or post decrement
- 1 unary minus
! 1 boolean complement
~ 1 bitwise complement
* 2 multiplication
/ 2 division
% 2 remainder
& 2 bitwise AND
| 2 bitwise OR
^ 2 bitwise XOR
<<, >> 2 left shift, right shift
+ 3 addition or string concatenation
- 3 subtraction
<, <= 4 less than, less than or equal
>, >= 4 greater than, greater than or equal
==, != 4 equal, not equal
&& 5 boolean AND
|| 5 boolean OR
= 6 assignment
+=, -=, *=, /= 6 assignment with operation

 

if/else Statements

The if statement conditionally executes other statements depending on the value of a boolean expression. It has the form:
   if (condition) {
      statement(s)
   }
The condition is evaluated. If it is true, the code block is executed, otherwise it is skipped. If at least one image is open, this example prints the title of the active image, otherwise it does nothing.
   if (nImages>0) {
      title = getTitle();
      print("title: " + title);
   }
An optional else statement can be included with the if statement:
   if (condition) {
      statement(s)
   } else {
      statement(s)
   }   
In this case, the code block after the else is executed if the condition is false. If no images are open, this example prints "No images are open", otherwise it prints the title of the active image.
   if (nImages==0)
      print("No images are open");
   else
      print("The image title is " + getTitle);
Note that the "==" operator is used for comparisons and the "=" operator is used for assignments. The braces are omitted in this example since they are not required for code blocks containing a single statement.

The macro language does not have a switch statement but it can be simulated using if/else statements. Here is an example:

   type = selectionType();
   if (type==-1)
      print("no selection");
   else if ((type>=0 && type<=4) || type==9)
      print("area selection");
   else if (type==10)
      print("point selection");
   else
      print("line selection");

Looping Statements (for, while and do...while)

Looping statements are used to repeatadly run a block of code. The ImageJ macro language has three looping statements: The for statement has the form:
   for (initialization; condition; increment) {
      statement(s)
   }
The initialization is a statement that runs once at the beginning of the loop. The condition is evaluated at top of each iteration of the loop and the loop terminates when it evaluates to false. Finally, increment is a statement that runs after each iteration through the loop.

In this example, a for loop is used to print the values 0, 10, 20...90.

   for (i=0; i<10; i++) {
      j = 10*i;
      print(j);
   }
The braces can be omitted if there is only one statement in the loop.
   for (i=0; i<=90; i+=10)
      print(i);
The while statement has the form:
   while (condition) {
      statement(s)
   }
First, the condition is evaluated. If it is true, the code block is executed and the while statement continues testing the condition and executing the code block until the condition becomes false.

In this example, a while loop is used to print the values 0, 10, 20...90.

   i = 0;
   while (i<=90) {
      print(i);
      i = i + 10;
   }
The do...while statement has the form:
   do {
      statement(s)
   } while (condition);
Instead of evaluating the condition at the top of the loop, do-while evaluates it at the bottom. Thus the code block is always executed at least once.

In this example, a do...while loop is used to print the values 0, 10, 20...90.

   i = 0;
   do {
      print(i);
      i = i + 10;
   } while (i<=90);

Working with Strings

Use the indexOf() function to test to see if one string is contained in another. Use the startsWith() and endsWith() functions to see if a string starts with or ends with another string. Use the substring() function to extract a portion of string. Use the lengthOf() function to determine the length of a string.

Use the "==", "!=", ">" and "<" operators to compare strings. Comparisons are case-insensitive. For example, the following code display true.

   ans = "Yes";
   if (ans=="yes")
       print ("true");
   else
      print("false");

User-defined functions

A function is a callable block of code that can be passed values and can return a value. The ImageJ macro language has two kinds of functions:
built-in and user-defined. A user-defined function has the form:
   function myFunction(argument1, argument2, etc) {
      statement(s)
   }
Functions can use the return statement to return a value.
   function sum(a, b) {
      return a + b;
   }
Functions defined with multiple arguments must be passed the same number of arguments. The sum() function has two arguments so it must called with two arguments.
    print(sum(1, 2));
A function with no arguments must include the parentheses
   function hello() {
      print("Hello");
   }
and, unlike built-in functions, must be called with parentheses.
   hello();