Execute ImageJ Macro from Java

@haesleinhuepf @imagejan
A collaborator developed an image processing workflow in the ImageJ Macro language. I would like to integrate this into my Java code without re-coding this in Java. Do you know how I could do this?

1 Like

I would do something like this:

#@ ScriptService scriptService

macro = "... your macro code here ..."
scriptService.run(".ijm", macro, true).get()

or

#@ ScriptService scriptService

macroFile = new File("/path/to/your/macro.ijm")
scriptService.run(macroFile, true).get()
2 Likes

… and if you’re not inside a SciJava related code section, you can get access to scijava services like this:

2 Likes

Thanks both of you for the fast and great help!

The input to and output of the macro is an ImagePlus.

Do you think there would be any way of doing things such that it runs headless, i.e. without “staging” the image by displaying it on the monitor?

One way would be via files, I guess? Is there a Fiji temp directory for such communication via files?

Any other, maybe scijava object service magic, way?

Yeah, the problem with the macro language is that it cannot have ImagePlus as real input or output (i.e. variables), but relies on the active (opened) image being processed.

Nevertheless, you should be able to use ij.WindowManager:

ImagePlus imp = ...

import ij.WindowManager
WindowManager.setTempCurrentImage(imp)

// [... call your macro here ...]

ImagePlus resultImp = WindowManager.getTempCurrentImage()
3 Likes

I tried but I am getting below error in the macro:

rename("input");


I guess I have to to something special in the macro to “get” the image?

1 Like

Interesting. I tried to reproduce, but don’t get the error you see.

Here’s what I did:

  • Open several images in the UI (e.g. some copies of boats.gif)
  • Run the following Groovy script, choosing one of the images in the background (i.e. a non-active image) for the second image input (I put two inputs to ensure that a dropdown is rendered; with newer versions of scijava-common, you can also use #@ ImagePlus (autofill=false) imp):
#@ ImagePlus imp1
#@ ImagePlus imp2

#@ ScriptService ss

import ij.WindowManager

macro = "rename(\"foo\"); print(getTitle);"

WindowManager.setTempCurrentImage(imp2)
ss.run(".ijm", macro, true).get()
result = WindowManager.getTempCurrentImage()

assert(result.getTitle().equals("foo"))

While I do see that the correct image was renamed in the UI image title and log window (i.e. the macro sees the correct image), I still get an assertion error :confused: :

Assertion failed: 

assert(result.getTitle().equals("foo"))
       |      |          |
       |      |          false
       |      'boats.gif'
       img["boats.gif" (-16), 8-bit, 720x576x1x1x1]

I see, I guess that means that the image is shown (even though in the background), is it?
What I tried (and ideally want to achieve) is that the ImagePlus object is not shown at all
(for batch running everything in headless mode). I played a bit with setBatchMode( true ) in the macro, but it seems it still needs the initial input image to be shown…

Hi @Christian_Tischer,
Not sure if an ImageJ1 solution would work for you, but this is how it’s done in the batch processor, for specifying input image and getting the output image.
Jerome.

1 Like

Thanks @jerome!

Apparently, one does not even need the WindowManger at all (not sure why it is in the code that you pointed to…?!).

// that works for me, a nice and easy one liner :-)
outputImp = new Interpreter().runBatchMacro( macro, inputImp );
3 Likes