I’d like to convert a large ImageJ Macro (1200lines) to a plugin. I’ve looked around the documentation, but all I can find about writing plugins is for Java. I’m a seasoned Java developer, but not really looking forward to rewriting 1200 lines of Macro code to Java. Is there any way to ease into that, for instance by running the macro code from within the plugin?
Good day Martin Van Dijken,
there is little hope for another approach than rewriting the macro in Java. The Recoder may help however. It can record macros and Java code as well as code for other scripting languages. My personal impression is that there is little difference in effort between the scripting languages (not the macro language) and Java.
Thanks for the answer Herbie, even though that was not what I was looking for
So you can confirm it is only possible to write Plugins in a JVM language such as Java?
ImageJ-plugins are written in Java.
To write plugins the ImageJ-1 way is really easy. Have a look at:
Most of ImageJ consists of plugins, even if it doesn’t look like this at the first glance. It has to do with the idea of modularity …
In the strict sense of “plugin”, yes, because it is defined as a Java class implementing
ij.plugin.PlugIn (for ImageJ 1.x) or
org.scijava.command.Command, for that matter, in ImageJ2/SciJava).
But really, there’s no need at all to go down that route.
You can have (almost) all the functionality with any of the supported scripting languages, and you can even implement plugin classes using Jython or Groovy.
But let me first ask: why do you think you have to convert your macro? Are you missing some functionality? If it is just for unit testing, version management, and/or continuous integration, you can simply include all your scripts in a single jar file, as illustrated by this project:
As a first step to make a 1200-line macro more managable, I’d suggest to split it into different functional units that each perform a specified task (either as functions within the same file, or as separate files).
If you elaborate a bit on your use case, and maybe post your macro here, someone here on the forum can help you more specifically.
Sorry for the late reply, was already working on the plugin and my day job at the same time, forgot all about this thread.
The reason I wanted to convert the macro into a plugin is because I wanted to put parts of it under test in order to prove the thing still works. The macro I was looking at was this one:
It’s got a user interface and then a bunch of calculations. I wanted to start working on it, so I wanted to put parts of it under test in order to prove I didn’t break it. I have started converting the macro to a plugin, but mostly just to learn how it does what it does and to get acquainted with ImageJ. Also, I will need to change the algorithm significantly for it to work for me and Java is the language I think I will do it with.
From the example-script-collection I don’t really understand how I could call the macro that you have packaged into the jar file from a unit testing stand point. Could you explain some?
I’ve added an example unit test on the
unit-tests branch. I don’t know if I’m doing it in the optimal way, but it demonstrates how you can run a script file using
ModuleService and test for the scripts outputs (defined by
@output script parameters).
I’m testing this minimal Groovy script:
… by running this Java test:
Hope it helps.
EDIT: you could also use Groovy for testing. You’d possibly need the
groovy-maven-plugin. Has anyone else done this already?
Ah, that’s pretty cool, using the ImageJ plugin framework to run other plugins. I can understand how this would help me run Groovy modules from a unit test. That isn’t too hard though, as I can simply call the code directly without relying on the Plugin system. Groovy code is compiled down to bytecode after all, same as Java.
If this also works for Macro’s, then it becomes a really cool way to reuse macros. Does it also work for macros?
The scripting framework and script parameters are supposed to be language-agnostic, so running a macro with
ModuleService works just as well.
The tricky part might be to figure out how you want to test the correct output, as the IJ1 macro language is designed to always work on the “active” image and doesn’t natively support the idea of output variables…
If you encounter problems with testing your transformed macro, I’d be happy to discuss further and try to help. In this case, it would be best if you can share your progress via github.