Difference between revisions of "How To Migrate Code From ImgLib To ImgLib2"

(Add more code tags; use source tags as appropriate)
 
(One intermediate revision by one other user not shown)
Line 4: Line 4:
  
 
All packages have changed prefix to avoid a name clash, and to conform to convention ([http://imglib2.net/ imglib2.net] now points to us):
 
All packages have changed prefix to avoid a name clash, and to conform to convention ([http://imglib2.net/ imglib2.net] now points to us):
* <code>mpicbg.imglib</code> -> <code>net.imglib2</code>
+
* <code>mpicbg.imglib</code> <code>net.imglib2</code>
  
 
Hence, it is easiest to perform a global search and replace for all instances of the old string with the new. This holds for all renames listed below.
 
Hence, it is easiest to perform a global search and replace for all instances of the old string with the new. This holds for all renames listed below.
  
 
Some core packages have also changed further:
 
Some core packages have also changed further:
* <code>mpicbg.imglib.image</code> -> <code>net.imglib2.img</code>
+
* <code>mpicbg.imglib.image</code> <code>net.imglib2.img</code>
  
 
== Rename classes ==
 
== Rename classes ==
  
 
In general, the Image class has been replaced with Img. Many classes with "Image" in the name have thus been changed to "Img" instead:
 
In general, the Image class has been replaced with Img. Many classes with "Image" in the name have thus been changed to "Img" instead:
* <code>Image</code> -> <code>Img</code>
+
* <code>Image</code> <code>Img</code>
* <code>ImageFactory</code> -> <code>ImgFactory</code>
+
* <code>ImageFactory</code> <code>ImgFactory</code>
* <code>ImageOpener</code> -> <code>ImgOpener</code>
+
* <code>ImageOpener</code> <code>ImgOpener</code>
  
 
Please note that there are cases where using Img is not appropriate, and a better alternative exists; see the [[Changes from ImgLib1 to ImgLib2]] page for a more complete explanation.
 
Please note that there are cases where using Img is not appropriate, and a better alternative exists; see the [[Changes from ImgLib1 to ImgLib2]] page for a more complete explanation.
Line 27: Line 27:
  
 
In addition, core methods for querying dimensional lengths have changed names:
 
In addition, core methods for querying dimensional lengths have changed names:
* <code>getNumDimensions()</code> -> numDimensions()
+
* <code>getNumDimensions()</code> → <code>numDimensions()</code>
* getDimension(int) -> dimension(int)
+
* <code>getDimension(int)</code> → <code>dimension(int)</code>
* getDimensions() -> dimensions(long[])
+
* <code>getDimensions()</code> → <code>dimensions(long[])</code>
  
 
For dimensions(long[]), note that it only populates an existing array. There is no method to allocate and return a new dimensional array. Instead, use the following code:
 
For dimensions(long[]), note that it only populates an existing array. There is no method to allocate and return a new dimensional array. Instead, use the following code:
  final long[] dims = new long[img.numDimensions()];
+
 
  img.dimensions(dims);
+
<source lang="java">
 +
final long[] dims = new long[img.numDimensions()];
 +
img.dimensions(dims);
 +
</source>
  
 
== Remove references to Container and ContainerFactory ==
 
== Remove references to Container and ContainerFactory ==
Line 42: Line 45:
  
 
There were previously three types: Cursor, LocalizableCursor and LocalizableByDimCursor. This is still true, but the terminology has changed: a cursor can now be "localizable"—meaning you can tell where it is in the dimensional structure—and/or "positionable"—meaning you can move the cursor to somewhere else. Essentially, the three kinds of cursors are now:
 
There were previously three types: Cursor, LocalizableCursor and LocalizableByDimCursor. This is still true, but the terminology has changed: a cursor can now be "localizable"—meaning you can tell where it is in the dimensional structure—and/or "positionable"—meaning you can move the cursor to somewhere else. Essentially, the three kinds of cursors are now:
# img.cursor() – returns a Cursor with "read-only" access to the dimensional position which is calculated on demand which might be an expensive calculation. Use when you don't care where you are in the structure (or only sparsely need this information), and want the most efficient path.
+
# <code>img.cursor()</code> – returns a Cursor with "read-only" access to the dimensional position which is calculated on demand which might be an expensive calculation. Use when you don't care where you are in the structure (or only sparsely need this information), and want the most efficient path.
# img.localizingCursor() – returns a Cursor with "read-only" access to the dimensional position.  Such Cursors track their position at each fwd() call and thus can calculate it more efficiently than the above.  Use when you always or often need to know where the cursor currently sits, but don't need to change the position other than normal iteration.
+
# <code>img.localizingCursor()</code> – returns a Cursor with "read-only" access to the dimensional position.  Such Cursors track their position at each fwd() call and thus can calculate it more efficiently than the above.  Use when you always or often need to know where the cursor currently sits, but don't need to change the position other than normal iteration.
# img.randomAccess() – returns a RandomAccess with "read-write" access to the dimensional position. Use when you need to change the position.
+
# <code>img.randomAccess()</code> – returns a RandomAccess with "read-write" access to the dimensional position. Use when you need to change the position.
  
 
Another way of looking at it is that Cursors are similar to InputStreams and must go forward, whereas RandomAccesses are similar to RandomAccessFiles and can seek back and forth at will.
 
Another way of looking at it is that Cursors are similar to InputStreams and must go forward, whereas RandomAccesses are similar to RandomAccessFiles and can seek back and forth at will.
Line 53: Line 56:
  
 
Here is an example:
 
Here is an example:
<code>
+
<source lang="java">
  ExtendedRandomAccessibleInterval< IntType, Img< IntType> > extendedInterval =
+
ExtendedRandomAccessibleInterval< IntType, Img< IntType> > extendedInterval =
    new ExtendedRandomAccessibleInterval< IntType, Img< IntType > >(
+
  new ExtendedRandomAccessibleInterval< IntType, Img< IntType > >(
        myIntImg,
+
      myIntImg,
        new OutOfBoundsMirrorFactory< IntType, Img< IntType > >( Boundary.DOUBLE ) );
+
      new OutOfBoundsMirrorFactory< IntType, Img< IntType > >( Boundary.DOUBLE ) );
  RandomAccess< IntType > randomAccess = extendedInterval.randomAccess();
+
RandomAccess< IntType > randomAccess = extendedInterval.randomAccess();
</code>
+
</source>
  
 
== Rename RGBLegacyType to ARGBType ==
 
== Rename RGBLegacyType to ARGBType ==
  
If you were using RGBALegacyType, note that it has changed to ARGBType, but serves the same purpose.
+
If you were using <code>RGBALegacyType</code>, note that it has changed to <code>ARGBType</code>, but serves the same purpose.
  
 
== Use net.imglib2.display.Projector instead of mpicbg.imglib.image.display.Display ==
 
== Use net.imglib2.display.Projector instead of mpicbg.imglib.image.display.Display ==
  
The Display class and corresponding packages are no longer applicable to ImgLib2. Instead, create a Projector. See the [http://fiji.sc/cgi-bin/gitweb.cgi?p=imglib.git;a=blob;f=imglib2/ui/src/main/java/net/imglib2/ui/ImgPanel.java;hb=refs/heads/master ImgPanel] class in the imglib-ui project for an example.
+
The Display class and corresponding packages are no longer applicable to ImgLib2. Instead, create a Projector.
  
 
== Additional issues ==
 
== Additional issues ==
Line 73: Line 76:
 
The RegionOfInterestCursor class is no longer available and its replacement is not yet in place. You'll need to work around this in the short term.
 
The RegionOfInterestCursor class is no longer available and its replacement is not yet in place. You'll need to work around this in the short term.
  
The Image.clone() method has been now named Img.copy().
+
The <code>Image.clone()</code> method has been now named <code>Img.copy()</code>.

Latest revision as of 15:05, 2 September 2017

ImgLib2 is a major redesign of ImgLib, and much has changed. This page attempts to provide a "how-to" guide for bringing existing ImgLib1 code up to date with ImgLib2. It is intended as a "quick start" guide—for more details, see the Changes from ImgLib1 to ImgLib2 page.

Rename packages

All packages have changed prefix to avoid a name clash, and to conform to convention (imglib2.net now points to us):

  • mpicbg.imglibnet.imglib2

Hence, it is easiest to perform a global search and replace for all instances of the old string with the new. This holds for all renames listed below.

Some core packages have also changed further:

  • mpicbg.imglib.imagenet.imglib2.img

Rename classes

In general, the Image class has been replaced with Img. Many classes with "Image" in the name have thus been changed to "Img" instead:

  • ImageImg
  • ImageFactoryImgFactory
  • ImageOpenerImgOpener

Please note that there are cases where using Img is not appropriate, and a better alternative exists; see the Changes from ImgLib1 to ImgLib2 page for a more complete explanation.

Use long for dimensional lengths

All dimensional lengths are now long (and long[]) instead of int (and int[]).

Rename dimensional length accessor methods

In addition, core methods for querying dimensional lengths have changed names:

  • getNumDimensions()numDimensions()
  • getDimension(int)dimension(int)
  • getDimensions()dimensions(long[])

For dimensions(long[]), note that it only populates an existing array. There is no method to allocate and return a new dimensional array. Instead, use the following code:

final long[] dims = new long[img.numDimensions()];
img.dimensions(dims);

Remove references to Container and ContainerFactory

Containers are now built in to the Img. For instance, PlanarImg (an implementation of Img) replaces PlanarContainer. Essentially, ContainerFactory and ImageFactory have been combined into ImgFactory. If you have code that creates a Container or ContainerFactory, it is no longer necessary—just create the correct kind of Img or ImgFactory instead (e.g., PlanarImgFactory).

Update cursor logic

There were previously three types: Cursor, LocalizableCursor and LocalizableByDimCursor. This is still true, but the terminology has changed: a cursor can now be "localizable"—meaning you can tell where it is in the dimensional structure—and/or "positionable"—meaning you can move the cursor to somewhere else. Essentially, the three kinds of cursors are now:

  1. img.cursor() – returns a Cursor with "read-only" access to the dimensional position which is calculated on demand which might be an expensive calculation. Use when you don't care where you are in the structure (or only sparsely need this information), and want the most efficient path.
  2. img.localizingCursor() – returns a Cursor with "read-only" access to the dimensional position. Such Cursors track their position at each fwd() call and thus can calculate it more efficiently than the above. Use when you always or often need to know where the cursor currently sits, but don't need to change the position other than normal iteration.
  3. img.randomAccess() – returns a RandomAccess with "read-write" access to the dimensional position. Use when you need to change the position.

Another way of looking at it is that Cursors are similar to InputStreams and must go forward, whereas RandomAccesses are similar to RandomAccessFiles and can seek back and forth at will.

Update out of bounds code

Out of bounds access is now handled differently. Previously you could pass an out of bounds strategy factory to a localizable cursor constructor. In a similar fashion now you extend an interval with an out of bounds strategy factory.

Here is an example:

ExtendedRandomAccessibleInterval< IntType, Img< IntType> > extendedInterval =
  new ExtendedRandomAccessibleInterval< IntType, Img< IntType > >(
      myIntImg,
      new OutOfBoundsMirrorFactory< IntType, Img< IntType > >( Boundary.DOUBLE ) );
RandomAccess< IntType > randomAccess = extendedInterval.randomAccess();

Rename RGBLegacyType to ARGBType

If you were using RGBALegacyType, note that it has changed to ARGBType, but serves the same purpose.

Use net.imglib2.display.Projector instead of mpicbg.imglib.image.display.Display

The Display class and corresponding packages are no longer applicable to ImgLib2. Instead, create a Projector.

Additional issues

The RegionOfInterestCursor class is no longer available and its replacement is not yet in place. You'll need to work around this in the short term.

The Image.clone() method has been now named Img.copy().