ImageJ StartupMacros

Before I lose this file again: StartupMacros.txt This is a text file, based on the original StartupMacros.txt file that came with ImageJ, that can be dropped in the ImageJ/macros folder that is created when you install ImageJ. Start up ImageJ, and if this macro doesn’t automatically run, go to Plugins>Macros>Startup Macros to load it. It installs a few more drawing tools on the ImageJ toolbar and creates some keyboard shortcuts for the following tools:

  • Line tool – press ‘l’
  • Brush tool – press ‘b’
  • Eraser tool – press ‘e’
  • Wand tool – press ‘w’

I either found or created some code found at the bottom of the file to create those shortcut keys. There’s also a shortcut bound to ‘k’ (for count, I don’t know) that converts an image to 8-bit grayscale, thresholds the image, and counts the resulting dots. That’s probably not useful for anyone else, but illustrates the results of using the macro recording facilities of ImageJ.

I use these keyboard shortcuts along side my drawing pad when measuring limpets. It’s quicker to hit a key on the keyboard than to find my mouse and click buttons on the ImageJ toolbar or try to do the same with the pen. There’s also the existing ‘m’ keyboard shortcut that makes a measurement of whatever is currently selected with the wand tool.

Most of the code below is not mine.

// "StartupMacros"
// The macros and macro tools in this file ("StartupMacros.txt") are 
// automatically installed in the Plugins>Macros submenu and
//  in the tool bar when ImageJ starts up.

//  About the drawing tools.
//  This is a set of drawing tools similar to the pencil, paintbrush, 
//  eraser and flood fill (paint bucket) tools in NIH Image. The 
//  pencil and paintbrush draw in the current foreground color 
//  and the eraser draws in the current background color. The
//  flood fill tool fills the selected area using the foreground color.
//  Hold down the alt key to have the pencil and paintbrush draw 
//  using the background color or to have the flood fill tool fill 
//  using the background color. Set the foreground and background 
//  colors by double-clicking on the flood fill tool or on the eye  
//  dropper tool.  Double-click on the pencil, paintbrush or eraser 
//  tool  to set the drawing width for that tool.
// Icons contributed by Tony Collins.

   // Global variables
   var pencilWidth=1,  eraserWidth=10, leftClick=16, alt=8;
   var brushWidth = 10; //call("ij.Prefs.get", "startup.brush", "10");
   var floodType =  "8-connected"; //call("ij.Prefs.get", "startup.flood", "8-connected");

   // The macro named "AutoRun" runs when ImageJ starts.
   // macro "AutoRun" {print("AutoRun");}

   // The macro named "AutoRunAndHide" runs when ImageJ starts
   // and the file containing it is not displayed when ImageJ opens it.
   // macro "AutoRunAndHide" {}

   //macro "AutoRun" {
      //run("My Plugin");

  //macro "Unused Tool -" {}

  var pmCmds = newMenu("Popup Menu",
       newArray("Help...", "Rename...", "Duplicate...", "Original Scale", 
       "Paste Control...", "-", "Record...", "Capture Screen ", "Monitor Memory...", 
       "List Commands...", "Control Panel...", "Startup Macros...", "Search..."));

  macro "Popup Menu" {
      cmd = getArgument();
      if (cmd=="Help...")
           showMessage("About Popup Menu",
               "To customize this menu, edit the line that starts with\n\"var pmCmds\" in ImageJ/macros/StartupMacros.txt.");

  macro "Abort Macro or Plugin (or press Esc key) Action Tool - CbooP51b1f5fbbf5f1b15510T5c10X" {

  var xx = requires138b(); // check version at install
  function requires138b() {requires("1.38b"); return 0; }

     var dCmds = newMenu("Developer Menu Tool",
      newArray("ImageJ Website","News", "Documentation", "ImageJ Wiki", "Resources", "Macro Language", "Macros", 
      "Macro Functions", "Startup Macros...", "Plugins", "Source Code", "Mailing List Archives", "-", "Record...", 
      "Capture Screen ", "Monitor Memory...", "List Commands...", "Control Panel...", "Search...", "Debug Mode"));

  macro "Developer Menu Tool - C037T0b11DT7b09eTcb09v" {
       cmd = getArgument();
       if (cmd=="ImageJ Website")
           run("URL...", "url=");
       else if (cmd=="News")
           run("URL...", "url=");
       else if (cmd=="Documentation")
           run("URL...", "url=");
       else if (cmd=="ImageJ Wiki")
           run("URL...", "url=");
       else if (cmd=="Resources")
           run("URL...", "url=");
       else if (cmd=="Macro Language")
           run("URL...", "url=");
       else if (cmd=="Macros")
           run("URL...", "url=");
        else if (cmd=="Macro Functions")
           run("URL...", "url=");
        else if (cmd=="Plugins")
           run("URL...", "url=");
        else if (cmd=="Source Code")
           run("URL...", "url=");
        else if (cmd=="Mailing List Archives")
           run("URL...", "url=");
        else if (cmd=="Debug Mode")
           setOption("DebugMode", true);
	 else if (cmd!="-")

  var sCmds = newMenu("Stacks Menu Tool", 
       newArray("Add Slice", "Delete Slice", "Next Slice [>]", "Previous Slice [<]", "Set Slice...", "-",
       "Convert Images to Stack", "Convert Stack to Images", "Make Montage...", "Reslice [/]...", "Z Project...",
       "3D Project...", "Plot Z-axis Profile", "-", "Start Animation", "Stop Animation", "Animation Options...",
       "-", "MRI Stack (528K)"));
  macro "Stacks Menu Tool - C037T0b11ST8b09tTcb09k" {
      cmd = getArgument();
      if (cmd!="-") run(cmd);

   macro "Pencil Tool - C037L494fL4990L90b0Lc1c3L82a4Lb58bL7c4fDb4L5a5dL6b6cD7b" {
        getCursorLoc(x, y, z, flags);
        if (flags&alt!=0)

  macro 'Pencil Tool Options...' {
       pencilWidth = getNumber("Pencil Width (pixels):", pencilWidth);

   macro "Paintbrush Tool - C037La077Ld098L6859L4a2fL2f4fL3f99L5e9bL9b98L6888L5e8dL888c" {
        getCursorLoc(x, y, z, flags);
        if (flags&alt!=0)

   macro 'Paintbrush Tool Options...' {
      brushWidth = getNumber("Brush Width (pixels):", brushWidth);
      call("ij.Prefs.set", "startup.brush", brushWidth);

    macro "Flood Fill Tool -C037B21P085373b75d0L4d1aL3135L4050L6166D57D77D68La5adLb6bcD09D94" {
        getCursorLoc(x, y, z, flags);
        if (flags&alt!=0) setColorToBackgound();
        floodFill(x, y, floodType);

   function draw(width) {
        getCursorLoc(x, y, z, flags);
        x2=-1; y2=-1;
        while (true) {
            getCursorLoc(x, y, z, flags);
            if (flags&leftClick==0) exit();
            if (x!=x2 || y!=y2)
            x2=x; y2 =y;

   function setColorToBackgound() {
       savep = getPixel(0, 0);
       makeRectangle(0, 0, 1, 1);
       background = getPixel(0, 0);
       run("Select None");
       setPixel(0, 0, savep);

  macro 'Flood Fill Tool Options...' {
      Dialog.create("Flood Fill Tool");
      Dialog.addChoice("Flood Type:", newArray("4-connected", "8-connected"), floodType);;
      floodType = Dialog.getChoice();
      call("ij.Prefs.set", "startup.flood", floodType);

  // This tool draws arrows. Double click on the tool icon
  // to set the width and length. Hold the shift key down to
  // constrain to mod 45 degree angles. Double click
  // on the eye dropper tool to define the color.
  // Press "z" to undo.
  var arrowWidth = 3;
  var arrowLength = -1;
  var arrowFirst = 1;
  var arrowLast = 1;
  macro "Arrow Tool (double click to configure) -C037L1ee1L65e1La9e1L65a9" {
      leftButton=16; rightButton=4; alt=8; shift=1;
      getCursorLoc(x, y, z, flags); 
      xstart = x; ystart = y; 
      x2=x; y2=y;
      setOption("disablePopupMenu", true); 
      while (flags&leftButton!=0) { 
          getCursorLoc(x, y, z, flags); 
          if (x!=x2 || y!=y2) {
              dx = x - xstart;
              dy = y - ystart;
              a = atan2(dy, dx)*180/PI;
              aa = abs(a);
              ra = sqrt(dx*dx + dy*dy);
              dx /= ra;
              dy /= ra;
              if (flags&shift!=0) {
                 s2 = sqrt(2)/2;
                 if (aa<=22.5||aa>=157.5)
                 else if (aa>=67.5&&aa<=112.5)                     dx=0;                 else if (a>22.5&&a<67.5)
                else if (a<-22.5&&a>-67.5)
                else if (a<-112.5&&a>-157.5)
               else if (a>112.5&&a<157.5)                     {dx=-s2;dy=s2;}               }               if (arrowLength>=0)
                 ra = arrowLength;
              x = xstart + dx*ra;
              y = ystart + dy*ra;
              makeLine(xstart, ystart, x, y);
          x2=x; y2=y; 
      setOption("disablePopupMenu", false);
       if (x!=xstart || y!=ystart)
          drawArrow(x2, y2, xstart, ystart, arrowWidth);
      run("Select None");   

  function drawArrow(x1, y1, x2, y2, arrowWidth) {
      size = 8+10*arrowWidth*0.5;
      dx = x2-x1;
      dy = y2-y1;
      ra = sqrt(dx*dx + dy*dy);
      dx /= ra;
      dy /= ra;
      x3 = x2-dx*size;
      y3 = y2-dy*size;
      r = 0.35*size;
      x4 = round(x3+dy*r);
      y4 = round(y3-dx*r);
      x5 = round(x3-dy*r);
      y5 = round(y3+dx*r);
      if (arrowLength==-1 || arrowLength>size)
         drawLine(x1, y1, x2-dx*size, y2-dy*size);

  macro "Arrow Tool (double click to configure) Options" {
      Dialog.create("Arrow Tool");
      Dialog.addString("Width:", arrowWidth);
      len = ""+arrowLength;
      if (arrowLength<0) len = "variable";
      Dialog.addString("Length:", len);;
      arrowWidth = parseInt(Dialog.getString());
      if (isNaN(arrowWidth)) arrowWidth = 3;
      arrowLength = parseInt(Dialog.getString());
      size = 8+10* arrowWidth*0.5;
      if (arrowLength<size) arrowLength=size;
      if (isNaN(arrowLength)) arrowLength=-1;

  macro "Set Drawing Color..."{ 
      run("Color Picker..."); 

  macro "-" {} //menu divider

  macro "About Startup Macros..." {
      path = getDirectory("macros")+"/About Startup Macros";
      if (!File.exists(path))
          exit("\"About Startup Macros\" not found in ImageJ/macros/.");

  macro "Save As JPEG... [j]" {
     quality = call("ij.plugin.JpegWriter.getQuality");
     quality = getNumber("JPEG quality (0-100):", quality);
     run("Input/Output...", "jpeg="+quality);

//Activate line tool by pressing lower case L button
macro "Line Tool [l]" {setTool(4);}  

//Activate brush tool
  macro "Paintbrush Toggle [b]" {
	while (true) {
		 getCursorLoc(x, y, z, flags);
       		 if (flags&alt!=0)

var eraserWidth=10;

//Install Eraser Tool
   macro "Eraser Tool - C037R0aa4 P0a61f1aa0Pbef5f1" { 

//Activate Eraser tool with 'e' key
macro "Eraser Toggle [e]" {

//Activate Wand tool with 'w' key
// Added by LPM 20130113
macro "Wand Toggle [w]" {

//This macro converts an image to 8-bit (grayscale), thresholds the image, and 
//counts the black spots in the resulting image using the Analyze Particles routine.
//Press the 'k' key to activate the macro. 
macro "Count dots [k]" {
	setThreshold(85, 255);
	run("Convert to Mask");
	run("Analyze Particles...", "size=30-Infinity circularity=0.00-1.00 show=Nothing summarize");