[ImageJ-devel] Problems prting plugIn to ImageJ2

Curtis Rueden ctrueden at wisc.edu
Fri Nov 9 13:32:13 CST 2012


Hi Michael,

> I've just started looking into to porting my existing ImageJ plugins
> to ImageJ2. I have hit a problem in that calls to functions like
> setDisplayRange seem not to take effect until my plugin returns.

Yes, that is expected behavior, and a consequence of how ImageJ2's legacy
layer works.

> The following plugin lets me interactively adjust the image display
> range when run with ImageJ1 but with ImageJ2 there is no effect to the
> image until I close the plugIn dialog.

Right. The rule of thumb is that IJ1 plugins which interactively alter an
image will not do so in ImageJ2, due to the way the legacy layer works.

> I also note that the ImageJ2 Adjust->Brightness/Contrast (appears new)
> can update the image interactively, whereas the Adjust->WindowLevel
> (looks like existing ImageJ1 UI) does not work.

We rewrote the Brightness/Contrast command specifically due to this issue.
The goal is to port all of ImageJ1's interactive plugins to ImageJ2, to
avoid this limitation in the legacy layer.

There is an ImageJ2 design page about backwards compatibility and the
legacy layer online at:
    http://developer.imagej.net/compatibility

We may be able to overcome the limitation with interactive plugins to an
extent, but it is difficult in general.

Another solution which is coming soon is that we are working on a toggle in
the Help menu to fully switch back and forth between ImageJ1 and ImageJ2
modes. The legacy layer will translate all data structures upon switch, so
you can run your interactive legacy plugins in ImageJ1 mode, then switch
back to ImageJ2 when finished.

When you say you want to port your existing ImageJ plugins, do you mean use
them in ImageJ2 via the legacy layer? (Which is what you have tried so
far.) Or fully update the code to use ImageJ2 data structures? For the
latter, the migration will be complete when no more ImageJ1 classes (ij.*)
are used, but only ImageJ2 classes (imagej.*). If you decide to go that
route, we would be very happy to help with the conversion process. The plan
is to write a plugin porting guide, but we do not have one yet.

Regards,
Curtis


On Wed, Nov 7, 2012 at 4:57 PM, Michael Ellis <michael.ellis at dsuk.biz>wrote:

> I've just started looking into to porting my existing ImageJ plugins to
> ImageJ2. I have hit a problem in that calls to functions like
> setDisplayRange seem not to take effect until my plugin returns.
>
> The following plugin lets me interactively adjust the image display range
> when run with ImageJ1 but with ImageJ2 there is no effect to the image
> until I close the plugIn dialog.
>
> I also note that the ImageJ2 Adjust->Brightness/Contrast (appears new) can
> update the image interactively, whereas the Adjust->WindowLevel (looks like
> existing ImageJ1 UI) does not work.
>
> Any help greatly appreciated!
>
>  Example code below
>
>
> //===========================================================================
>
>
> package SmartCapture;
>
> import java.awt.AWTEvent;
> import ij.IJ;
> import ij.ImagePlus;
> import ij.gui.DialogListener;
> import ij.gui.GenericDialog;
> import ij.plugin.filter.ExtendedPlugInFilter;
> import ij.plugin.filter.PlugInFilterRunner;
> import ij.process.ImageProcessor;
>
> public class Test_IJ2 implements ExtendedPlugInFilter, DialogListener {
>
>  private final static String PLUGIN_NAME = Test_IJ2.class.getSimpleName();
>
>  private static int FLAGS = // bitwise or of the following flags:
>  DOES_8G | KEEP_PREVIEW; // When using preview, the preview image can be
> kept as a result
>
>  ImagePlus imp;
>  private double low;
>  private double high;
>
>  public int setup(String arg, ImagePlus imp) {
>
> if (imp == null) {
>  IJ.error(PLUGIN_NAME, "No image.\nOpen or create an image first then run
> "
>  + PLUGIN_NAME);
>  return DONE;
>  }
>
> this.imp = imp;
>
>  return FLAGS;
>  }
>
>  public int showDialog(ImagePlus imp, String command, PlugInFilterRunner
> pfr) {
>
> assert (imp != null);
>  if (imp == null)
>  return DONE;
>
>  GenericDialog gd = new GenericDialog(PLUGIN_NAME + "...");
>  gd.addMessage(imp.getTitle());
>  gd.addSlider("low", 0, 255, 0);
>  gd.addSlider("high", 0, 255, 255);
>  gd.addPreviewCheckbox(pfr, " Preview");
>  gd.addDialogListener(this);
>  gd.showDialog(); // user input (or reading from macro) happens here
>  if (gd.wasCanceled()) // dialog cancelled?
>  return DONE;
>  return IJ.setupDialog(imp, FLAGS);
>  }
>
> public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
>
>  low = gd.getNextNumber();
>  high = gd.getNextNumber();
>  IJ.log(String.format("low=%g high=%g\n", low, high));
>
>  return true;
>  }
>
>  public void run(ImageProcessor ip) {
>  IJ.log("run called\n");
>  imp.setDisplayRange(low, high);
>  }
>
>  public void setNPasses(int nPasses) {
>  IJ.log(String.format("setNPasses(%d)\n", nPasses));
>  }
>
> }
>
>
> _______________________________________________
> ImageJ-devel mailing list
> ImageJ-devel at imagej.net
> http://imagej.net/mailman/listinfo/imagej-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20121109/e2bb49c5/attachment-0001.html>


More information about the ImageJ-devel mailing list