Command line recording of ImageJ2 plugins

Tags: #<Tag:0x00007fb87e487f40>



I am writing code such that an ImageJ2 plugin would automatically print what would be needed for it to be run from command line, e.g.

"Plugin Name" "parameter1='1',parameter2='2"

My idea is that one can then simply put

ImageJ-binary --ij2 --run

in front of it and can run the IJ2 plugin from command line.

My issue is that I did not find an elegant way to automatically generate above parameter String, because parameter1 is the name of the java variable and not a string…

Is there a good way?


Great! I think this should even go into a scijava component to make it more generally usable. There have been plans since a long time to have a language-agnostic recorder:

So when this gets implemented, it would be straight-forward to record in any script language, or in “CLI” mode as you suggest.

This would be a great topic for the next hackathon :slight_smile:

When you have a Module m, you can query its input keys and values using m.getInputs() which will give you a Map<String,Object> that would contain parameter1 as a String key in your case.

Also, the MacroRecorderPostprocessor does something similar already, making all SciJava modules macro-recordable:


What is the best way of making an IJ2 plugin a Module?

Normally, I am defining plugins like this:

@Plugin(type = Command.class, menuPath = "Plugins>MyPlugin) public class AnalyzeObjectsCommand implements Command

But this is not enough as Command does not implement Module. The way I did it now is by extending DynamicCommand. Is that the way to do t?

@Plugin(type = Command.class, menuPath = "Plugins>MyPlugin) public class AnalyzeObjectsCommand extends DynamicCommand


The API of ModuleService, CommandService and ScriptService is rather stable, and the modular and extensible architecture of SciJava and ImageJ ensures you can build upon this even if the actual implementation of those services is still subject to change in the future.

One way you can achieve this exists already: it’s called KNIME :wink: (and in particular the knip-imagej2 integration that is hopefully going to be replaced by an improved knip-scijava integration some time in the future, see also this GitHub issue).

Every Command you write (as long as it’s annotated with headless=true) will auto-generate its node in KNIME, and you can just chain them together. (For some very simple examples illustrating this, see the fmi-ij2-plugins repository.)

There’s of course lots of room for improvement and further development, as always.

Why don’t you describe your application more specifically, either here on the forum (in a new topic), or by creating an example repository on GitHub, so we can collaboratively solve some real-world use cases?


Do you have also ImageJ examples (without using KNIME) about chaining Modules together into a Workflow?

I guess one would someone specify that the output of one Module is the input of the next one?

Related to this I found lines of code like below in your examples:

@Parameter(type = ItemIO.OUTPUT) private Img<T> output;

Could you explain a bit what that does?


Sorry for dropping the ball on this one until now.

Output parameters are briefly explained on the script parameters documentation page. By default, parameters are considered being INPUT, but you can annotate them as OUTPUT or BOTH as well. The definition of those is in org.scijava.ItemIO:

To see an example of using the ModuleService to run a script and get its outputs, you can have a look at this example:

that I added in response to this discussion:

Also have a look at this example notebook that can be run interactively here:


Hi Jan,

The link above regarding how to use the ModuleService does not work for me as it points to an issue, rather than to code.


The link I posted was the pull request. You can see the changed files if you click the “Files changed” tab on that page.

For your convenience, here’s the direct link to the diff of