Image Editor Tips - Writing Plugins

The Image Editor is built almost entirely from plugins. That is, every menu item, tool, palette, filter, file importer and exporter is a plugin. This may not be apparent at first because a lot of the 'plugins' are built into the application, but it's easy to remove them by editing a confiuration file. This page explains how to add your own plugin filters to the image editor. I haven't documented writing other types of plugin so far but this is purely due to lack of time, and I'll get round to it eventually.

Adding a new filter plugin is a fairly simple process, the filter plugins are simply instances of java.awt.image.ImageFilter (no longer recommended) or java.awt.image.BufferedImageOp, so you can add many existing filters as plugins. However there are a few rules to follow:

  • Your filter must have a default constructor.
  • In order for it to have a sensible name in the Filters menu, you should provide one in the filter's toString() method.
  • You need to package the filter as a JavaBean.

As an example, let's add this filter which simply multiplies all the pixels in an image by a scaling factor. Note the default constructor and the toString() method. This last should return a name in the form <group>/<filter>. The image editor will put all filters in the same group into a submenu with the group's name.

import java.awt.*;
import java.awt.image.*;

public class RescaleFilter extends TransferFilter {

	private float scale = 1.0f;
	
	protected int transferFunction(int v) {
		return PixelUtils.clamp((int)(v * scale));
	}

	public void setScale(float scale) {
		this.scale = scale;
		initialized = false;
	}
	
	public float getScale() {
		return scale;
	}

	public String toString() {
		return "Colors/Rescale...";
	}

}

Next we need to tell the Image Editor how to display a dialog to let the user change the scaling factor, This can be done in two ways: you can provide a JavaBeans customizer or do it the easy way. The easy way is to provide an XML file which lists the properties the editor should show. The file should be in the same locaiton as the filter class - it will be loaded using filter.getClass().getResource("<FilterName>"). Here's the file we need for the RescaleFilter:

<filters>
    <filter class='com.jhlabs.image.RescaleFilter' group='Colors'>
        <param property='scale' name='Scale' type='float' min='0' max='5'/>
    </filter>
</filters>

It's fairly self-explanatory and I'm not going to go into great details here other than to list the property types which are supported. These are: int, float, angle (in degrees), color (as an ARGB integer), image (a BufferedImage), colormap, boolean, percentage (a float in the range 0..1), and choice (as an integer 0..n). The last of these requires an extra parameter to give the choices, e.g. choices='Tomato|Cheese|Anchovy'.

All you need to do now is to compile the filter and put its class file (and XML file if you have one) into the image editor "plugins" folder before starting up the editor. The filter should appear as a menu item Filters->Colors->Rescale... If your filter consists of more than one class or has a customizer, you should package it as a Java Bean. That is, you should place it in a JAR file and mark it as a Java-Bean in the manifest, then place the JAR file in the plugins folder. You can package multiple filters in the same JAR file with this method.

If your filter has a customizer component it should have the same name as the filter with the word "Customizer" on the end. The image editor will not use the BeanInfo customizer because I don't want to force every filter to have a BeanInfo class written for it (a most tedious process).

Where's the plugins folder? The editor looks first for a folder called "plugins" in the folder which contains ImageEditor.jar. Next it looks for a folder called "plugins" in the current working folder, which depends on your operating system and how you invoked the editor, and may or may not be the same as the first folder (it won't load the same plugins twice). On Mac OS X, it will also look in ~/Library/Application Support/Image Editor and /Library/Application Support/Image Editor. You can also pass -DpluginsFolder=/path/to/folder on the command line.

That's it! Have fun.