Friday, December 23, 2011

Drawing arrows in IJ script



Drawing arrows in a ImageJ macro/script is sometimes useful to display direction of a feature (oriented lines of interest, gradient,etc.)  but this simple drawing isn't so straightforward...


1- Understanding how an arrow is drawn
In ImageJ, an arrow is a specialized line and thus belongs to the line tools family (Tool #5 in the toolbar).  To draw interactively an arrow, you choose the Arrow Tool in the sub-menu of Tool #5 (Fig.1) 
Fig.1: Selection of the arrow tool by right-clicking on Tool #5 and choosing the item 'Arrow Tool' in the sub-menu.
 and then you click and drag a line in your target image. Finally, you draw this selection with the function Edit > Draw or Ctrl+D.
Fig.2: Drawing an arrow. A) Click and drag the arrow. B) Draw with the current foreground color by choosing Edit > Draw (or Ctrl+D as shortcut).
To tune the various parameters of the arrow ( line width, head size, double/single head,etc.), you can double-click on Tool #5 or select the Edit > Options > Arrow Tool... and a dialog box is displayed (Fig. 3).
Fig.3: Arrow Tool dialog box displayed by double-clicking on Tool #5.
2- Drawing an arrow in a IJ macro/script
The tricky part is the arrow drawing in a macro. Indeed, according to the recorder (Plugins > Macros > Record...), the IJ script should be ...
run("Arrow Tool...", "width=1 size=4 color=black style=Filled");
makeLine(184, 20, 72, 141);
run("Draw");
... unfortunately, it doesn't work (in my current version IJ 1.46c).

However, thanks to the trick posted by J. Mutterer in the ImageJ mailing list, the solution consists of creating an arrow in JavaScript and running it in IJ scripting language via the function eval(...).
To create an arrow in JavaScript, the code looks like ...
// get image ID
img = IJ.getImage();
// Create the arrow
a= new Arrow(184, 20, 72, 141);
// Set various parameters
a.setHeadSize(4);
a.setStrokeWidth(1);
a.setStyle(Arrow.FILLED);
img.setRoi(a);
To insert JavaScript code in a IJ macro/script language, the function eval(...) is used as followed...
eval('script',javascript_code); // where javascript_code is a String.
Now, a simple function drawArrow(...) looks like ...

+++ IJ snippet +++ +++ End of IJ snippet +++

This function can be improved to take into account the head size and stroke width that are hardcoded in my version.

No comments:

Post a Comment