In the previous chapter you saw how to install a plugin that is available for download from the developer website. We also introduced some of them that are potentially useful in a wide range of applications. This chapter includes the following:
This chapter will require prior programming experience, ideally with Java, but there is nothing here outside the concepts handled by other object oriented programming languages.
We will start digging into this topic by analyzing the following plugin code. That will give us a nice starting point to introduce the different aspects for developing ImageJ plugins:
import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; import ij.plugin.frame.*; public class Test_Plugin implements PlugIn { public void run(String arg) { int width = 300; int height = 300; ImageProcessor ip = new ByteProcessor(width, height); ip.setColor(Color.black); ip.fill(); for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { if (x == y || (width - x) == y) ip.putPixel(x, y, 255); } } ImagePlus imp = new ImagePlus("Result image", ip); imp.show(); } }
First things first: this is a plugin, and not a macro. To edit it, navigate to Plugins | New | Plugin. A sample skeleton will be opened and you just need to fill in the run(arg)
method (previously, delete the example code that is inside it). When you are done, save the plugin in the ImageJ plugins
folder of your working ImageJ installation. The editor is smart enough to change the name of your class to match the name of the file, as Java requires. Also, your class name must contain at least one underscore (_
), or ImageJ will not find it. Remember to use the .java
extension for the file.
For advanced users: if you build a JAR file and place inside it plugins.config
file that defines which classes are plugins, then there is no need of underscore in the name. In any case, this option is outside the scope of this book, but we wanted to place this warning here, so that you do not think that the underscore is always mandatory.
After completing these steps, you will have a .java
file in your plugins
folder. Now you need to compile it so that ImageJ can run it. This is done from the editing window, by navigating to File | Compile and then Run (Ctrl + R). If you do not have a Java Development Kit installed in your computer, then ImageJ will offer to download the Compiler.jar
plugin, which will allow you to compile new plugins without the need to modify your Java installation. Click on OK on the dialog that shows up if that happens, as you will need it.
If everything has gone according to the plan, now you will also have a Test_Plugin.class
file in your plugins
folder, and the following screenshot will be displayed:
We have just run our first ImageJ plugin developed by ourselves. This time, we had to do it from the Compile and Run menu options in the editor window. As the .class
file is now in your plugins
folder, the next time you restart ImageJ you will see a Test Plugin option in the Plugin menu in the main ImageJ window. Let's go through the code in small chunks, so that you understand what we are doing.
The first lines include all the necessary library imports and are added automatically by the ImageJ proposed skeleton. If you need to use some other library, put your import here. Then we declare our Test_Plugin
class, which implements an interface called PlugIn
. There are several ways to code ImageJ plugins, depending on which interface we are implementing, but in this book we are going to focus on two of them: PlugIn
and
PlugInFilter
. Depending on the purpose of our plugin, we will be using one or the other.
The PlugIn
interface needs us to implement just one method, run(String arg)
, that is immediately executed when the plugin is run. The PlugInFilter
needs two methods, setup(String arg, ImagePlus imp)
and run(ImageProcessor ip)
. The setup
method is the first one that is being run and checks whether the image to which the plugin is being applied (the ImagePlus
object passed as reference) has certain properties. Note that we are ignoring the String arg
parameter, as it is outside the scope of this book and is not really needed to build powerful plugins. We can make the following distinction: a PlugIn
interface implementation can be run in a standalone fashion and the
PlugInFilter
is applied to an already opened image, just similar to what a macro does. This is a very rough division but it is the one we will use in this book. We will work a bit with the PlugInFilter
interface next in this section. For now, let's keep going through our code.
In the run
method of our example we create a new square (300
x 300
) ImageProcessor
object. This is an abstract class that needs to be instantiated depending on the type of image we want to use. In this case, as we are working with a simple 8-bit image, we create a
ByteProcessor
object with width
and height
as parameters. We can also use a
ShortProcessor
object (16-bit unsigned data), BinaryProcessor
(similar to ByteProcessor
, but its pixel values can only take two values: 0
or 255
),
FloatProcessor
(32-bit floating point values), or ColorProcessor
(32-bit RGB image). Once the
ImageProcessor
object has been created, we can start using its methods to modify its pixel values.
The next thing we do is to set the color chooser to black (ip.setColor(Color.black)
) and fill the current ROI with it (ip.fill()
). As we have not defined any ROI, this method fills the whole image with the black color.
Next we create two nested for
loops (one for the x axis, another for the y axis) and iterate through all the image pixels, by setting those belonging to either diagonal with the ip.putPixel(x, y, value)
method to 255
.
After this step, the actual processing is finished. All that is left is to create an ImagePlus
object with a title and the pixel contents of the
ImageProcessor
object and show it on the screen. An
ImagePlus
object also contains the image's metadata, such as the spatial scale or the calibration. Note that the run
method for this interface does not return anything. You must compute all the resulting images and show them on the screen.