diff --git a/src/main/java/bdv/ij/OpenImagePlusPlugIn.java b/src/main/java/bdv/ij/OpenImagePlusPlugIn.java index 8d8bdfa39cb00a2e076745f85a3d227a95622e52..6e29dbaf521b9948bab78ecb0e017a307443fe81 100644 --- a/src/main/java/bdv/ij/OpenImagePlusPlugIn.java +++ b/src/main/java/bdv/ij/OpenImagePlusPlugIn.java @@ -56,21 +56,8 @@ public class OpenImagePlusPlugIn implements Command { System.setProperty( "apple.laf.useScreenMenuBar", "true" ); new ImageJ(); - - -// IJ.run("Confocal Series (2.2MB)"); -// IJ.run("Confocal Series (2.2MB)"); -// IJ.run("Fly Brain (1MB)"); - -// ImagePlus ip1 = IJ.openImage("/groups/saalfeld/home/bogovicj/tmp/mri-stack.tif"); -// ImagePlus ip2 = IJ.openImage("/groups/saalfeld/home/bogovicj/tmp/flybrain.tif"); - - ImagePlus ip1 = IJ.openImage("/groups/saalfeld/home/bogovicj/tmp/confocal-series.tif"); - ImagePlus ip2 = IJ.openImage("/groups/saalfeld/home/bogovicj/tmp/confocal_grad.tif"); - - ip1.show(); - ip2.show(); - + IJ.run( "Confocal Series (2.2MB)" ); +// IJ.run( "Fly Brain (1MB)" ); new OpenImagePlusPlugIn().run(); } @@ -109,17 +96,19 @@ public class OpenImagePlusPlugIn implements Command AbstractSpimData< ? > spimData; CacheControl cache = null; int setup_id_offset = 0; + ArrayList<ImagePlus> imgList = new ArrayList<ImagePlus>(); for( int i = 0; i < nImages; i++ ) { if( !gd.getNextBoolean() ) continue; ImagePlus imp = WindowManager.getImage( idList[ i ]); + imgList.add( imp ); spimData = load( imp, converterSetups, sources, setup_id_offset ); if( spimData != null ) cache = ( ( ViewerImgLoader ) spimData.getSequenceDescription().getImgLoader() ).getCacheControl(); - setup_id_offset += imp.getChannel(); + setup_id_offset += imp.getNChannels(); } int nTimepoints = 1; @@ -131,17 +120,15 @@ public class OpenImagePlusPlugIn implements Command final VisibilityAndGrouping vg = bdv.getViewer().getVisibilityAndGrouping(); vg.setFusedEnabled( true ); - int channel_offset = 0; - for( int i = 0; i < nImages; i++ ) + int channelOffset = 0; + for( ImagePlus imp : imgList ) { - ImagePlus imp = WindowManager.getImage( idList[ i ]); if ( imp.isComposite() ) - { - transferChannelSettings( channel_offset, ( CompositeImage ) imp, sa, vg ); - channel_offset += imp.getNChannels(); - } + transferChannelSettings( channelOffset, ( CompositeImage ) imp, sa, vg ); else - transferImpSettings( imp, sa ); + transferImpSettings( channelOffset, imp, sa ); + + channelOffset += imp.getNChannels(); } } @@ -184,9 +171,6 @@ public class OpenImagePlusPlugIn implements Command // propose reasonable mipmap settings // final ExportMipmapInfo autoMipmapSettings = ProposeMipmaps.proposeMipmaps( new BasicViewSetup( 0, "", size, voxelSize ) ); -// imp.getDisplayRangeMin(); -// imp.getDisplayRangeMax(); - // create ImgLoader wrapping the image final BasicImgLoader imgLoader; if ( imp.getStack().isVirtual() ) @@ -194,17 +178,17 @@ public class OpenImagePlusPlugIn implements Command switch ( imp.getType() ) { case ImagePlus.GRAY8: - imgLoader = VirtualStackImageLoader.createUnsignedByteInstance( imp ); + imgLoader = VirtualStackImageLoader.createUnsignedByteInstance( imp, setup_id_offset ); break; case ImagePlus.GRAY16: - imgLoader = VirtualStackImageLoader.createUnsignedShortInstance( imp ); + imgLoader = VirtualStackImageLoader.createUnsignedShortInstance( imp, setup_id_offset ); break; case ImagePlus.GRAY32: - imgLoader = VirtualStackImageLoader.createFloatInstance( imp ); + imgLoader = VirtualStackImageLoader.createFloatInstance( imp, setup_id_offset ); break; case ImagePlus.COLOR_RGB: default: - imgLoader = VirtualStackImageLoader.createARGBInstance( imp ); + imgLoader = VirtualStackImageLoader.createARGBInstance( imp, setup_id_offset ); break; } } @@ -213,17 +197,17 @@ public class OpenImagePlusPlugIn implements Command switch ( imp.getType() ) { case ImagePlus.GRAY8: - imgLoader = ImageStackImageLoader.createUnsignedByteInstance( imp ); + imgLoader = ImageStackImageLoader.createUnsignedByteInstance( imp, setup_id_offset ); break; case ImagePlus.GRAY16: - imgLoader = ImageStackImageLoader.createUnsignedShortInstance( imp ); + imgLoader = ImageStackImageLoader.createUnsignedShortInstance( imp, setup_id_offset ); break; case ImagePlus.GRAY32: - imgLoader = ImageStackImageLoader.createFloatInstance( imp ); + imgLoader = ImageStackImageLoader.createFloatInstance( imp, setup_id_offset ); break; case ImagePlus.COLOR_RGB: default: - imgLoader = ImageStackImageLoader.createARGBInstance( imp ); + imgLoader = ImageStackImageLoader.createARGBInstance( imp, setup_id_offset ); break; } } @@ -235,9 +219,9 @@ public class OpenImagePlusPlugIn implements Command final HashMap< Integer, BasicViewSetup > setups = new HashMap<>( numSetups ); for ( int s = 0; s < numSetups; ++s ) { - final BasicViewSetup setup = new BasicViewSetup( s, String.format( imp.getTitle() + " channel %d", s + 1 ), size, voxelSize ); - setup.setAttribute( new Channel( setup_id_offset + s + 1 ) ); - setups.put( s, setup ); + final BasicViewSetup setup = new BasicViewSetup( setup_id_offset + s, String.format( imp.getTitle() + " channel %d", s + 1 ), size, voxelSize ); + setup.setAttribute( new Channel( s + 1 ) ); + setups.put( setup_id_offset + s, setup ); } // create timepoints @@ -252,7 +236,7 @@ public class OpenImagePlusPlugIn implements Command final ArrayList< ViewRegistration > registrations = new ArrayList<>(); for ( int t = 0; t < numTimepoints; ++t ) for ( int s = 0; s < numSetups; ++s ) - registrations.add( new ViewRegistration( t, s, sourceTransform ) ); + registrations.add( new ViewRegistration( t, setup_id_offset + s, sourceTransform ) ); final File basePath = new File("."); final AbstractSpimData< ? > spimData = new SpimDataMinimal( basePath, seq, new ViewRegistrations( registrations ) ); @@ -262,7 +246,7 @@ public class OpenImagePlusPlugIn implements Command return spimData; } - protected void transferChannelSettings( int channel_offset, final CompositeImage ci, final SetupAssignments setupAssignments, final VisibilityAndGrouping visibility ) + protected void transferChannelSettings( int channelOffset, final CompositeImage ci, final SetupAssignments setupAssignments, final VisibilityAndGrouping visibility ) { final int nChannels = ci.getNChannels(); final int mode = ci.getCompositeMode(); @@ -270,7 +254,7 @@ public class OpenImagePlusPlugIn implements Command for ( int c = 0; c < nChannels; ++c ) { final LUT lut = ci.getChannelLut( c + 1 ); - final ConverterSetup setup = setupAssignments.getConverterSetups().get( channel_offset + c ); + final ConverterSetup setup = setupAssignments.getConverterSetups().get( channelOffset + c ); if ( transferColor ) setup.setColor( new ARGBType( lut.getRGB( 255 ) ) ); setup.setDisplayRange( lut.min, lut.max ); @@ -286,9 +270,9 @@ public class OpenImagePlusPlugIn implements Command visibility.setCurrentSource( ci.getChannel() - 1 ); } - protected void transferImpSettings( final ImagePlus imp, final SetupAssignments setupAssignments ) + protected void transferImpSettings( int setupIndex, final ImagePlus imp, final SetupAssignments setupAssignments ) { - final ConverterSetup setup = setupAssignments.getConverterSetups().get( 0 ); + final ConverterSetup setup = setupAssignments.getConverterSetups().get( setupIndex ); setup.setDisplayRange( imp.getDisplayRangeMin(), imp.getDisplayRangeMax() ); } } diff --git a/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java b/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java index d3f3eeda0ac51fa5fb73ef05003d98d9c1f39e4f..f5f6528073839557d562b824a89880113c8d3edb 100644 --- a/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java +++ b/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java @@ -1,6 +1,7 @@ package bdv.img.imagestack; import java.util.ArrayList; +import java.util.HashMap; import java.util.function.Function; import net.imglib2.RandomAccessibleInterval; @@ -28,22 +29,42 @@ public class ImageStackImageLoader< T extends NumericType< T > & NativeType< T > { public static ImageStackImageLoader< UnsignedByteType, ByteArray > createUnsignedByteInstance( final ImagePlus imp ) { - return new ImageStackImageLoader<>( new UnsignedByteType(), imp, array -> new ByteArray( ( byte[] ) array ) ); + return createUnsignedByteInstance( imp, 0 ); + } + + public static ImageStackImageLoader< UnsignedByteType, ByteArray > createUnsignedByteInstance( final ImagePlus imp, int offset ) + { + return new ImageStackImageLoader<>( new UnsignedByteType(), imp, array -> new ByteArray( ( byte[] ) array ), offset ); } public static ImageStackImageLoader< UnsignedShortType, ShortArray > createUnsignedShortInstance( final ImagePlus imp ) { - return new ImageStackImageLoader<>( new UnsignedShortType(), imp, array -> new ShortArray( ( short[] ) array ) ); + return createUnsignedShortInstance( imp, 0 ); + } + + public static ImageStackImageLoader< UnsignedShortType, ShortArray > createUnsignedShortInstance( final ImagePlus imp, int offset ) + { + return new ImageStackImageLoader<>( new UnsignedShortType(), imp, array -> new ShortArray( ( short[] ) array ), offset ); } public static ImageStackImageLoader< FloatType, FloatArray > createFloatInstance( final ImagePlus imp ) { - return new ImageStackImageLoader<>( new FloatType(), imp, array -> new FloatArray( ( float[] ) array ) ); + return createFloatInstance( imp, 0 ); + } + + public static ImageStackImageLoader< FloatType, FloatArray > createFloatInstance( final ImagePlus imp, int offset ) + { + return new ImageStackImageLoader<>( new FloatType(), imp, array -> new FloatArray( ( float[] ) array ), offset ); } public static ImageStackImageLoader< ARGBType, IntArray > createARGBInstance( final ImagePlus imp ) { - return new ImageStackImageLoader<>( new ARGBType(), imp, array -> new IntArray( ( int[] ) array ) ); + return createARGBInstance( imp, 0 ); + } + + public static ImageStackImageLoader< ARGBType, IntArray > createARGBInstance( final ImagePlus imp, int offset ) + { + return new ImageStackImageLoader<>( new ARGBType(), imp, array -> new IntArray( ( int[] ) array ), offset ); } private final T type; @@ -52,35 +73,39 @@ public class ImageStackImageLoader< T extends NumericType< T > & NativeType< T > private final long[] dim; - private final ArrayList< SetupImgLoader > setupImgLoaders; + private final HashMap< Integer, SetupImgLoader > setupImgLoaders; private final Function< Object, A > wrapPixels; - public ImageStackImageLoader( final T type, final ImagePlus imp, final Function< Object, A > wrapPixels ) + public ImageStackImageLoader( final T type, final ImagePlus imp, final Function< Object, A > wrapPixels, int setup_id_offset ) { this.type = type; this.imp = imp; this.wrapPixels = wrapPixels; this.dim = new long[] { imp.getWidth(), imp.getHeight(), imp.getNSlices() }; final int numSetups = imp.getNChannels(); - setupImgLoaders = new ArrayList<>(); - for ( int setupId = 0; setupId < numSetups; ++setupId ) - setupImgLoaders.add( new SetupImgLoader( setupId ) ); + setupImgLoaders = new HashMap<>(); + for ( int c = 0; c < numSetups; ++c ) + setupImgLoaders.put( (setup_id_offset + c), new SetupImgLoader( c ) ); + } + + public ImageStackImageLoader( final T type, final ImagePlus imp, final Function< Object, A > wrapPixels ) + { + this( type, imp, wrapPixels, 0 ); } public class SetupImgLoader implements BasicSetupImgLoader< T > { - private final int setupId; + private final int channel; - public SetupImgLoader( final int setupId ) + public SetupImgLoader( final int channel ) { - this.setupId = setupId; + this.channel = channel + 1; } @Override public RandomAccessibleInterval< T > getImage( final int timepointId, final ImgLoaderHint... hints ) { - final int channel = setupId + 1; final int frame = timepointId + 1; final ArrayList< A > slices = new ArrayList<>(); for ( int slice = 1; slice <= dim[ 2 ]; ++slice ) diff --git a/src/main/java/bdv/img/virtualstack/VirtualStackImageLoader.java b/src/main/java/bdv/img/virtualstack/VirtualStackImageLoader.java index 30e06c216326e6ca9e3010fad389ed9fa371499f..cf73f1ecbea142c2f7cfca007ed26e4121ab1cad 100644 --- a/src/main/java/bdv/img/virtualstack/VirtualStackImageLoader.java +++ b/src/main/java/bdv/img/virtualstack/VirtualStackImageLoader.java @@ -1,6 +1,7 @@ package bdv.img.virtualstack; import java.util.ArrayList; +import java.util.HashMap; import bdv.AbstractViewerSetupImgLoader; import bdv.ViewerImgLoader; @@ -62,9 +63,14 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte implements ViewerImgLoader, TypedBasicImgLoader< T > { public static VirtualStackImageLoader< FloatType, VolatileFloatType, VolatileFloatArray > createFloatInstance( final ImagePlus imp ) + { + return createFloatInstance( imp, 0 ); + } + + public static VirtualStackImageLoader< FloatType, VolatileFloatType, VolatileFloatArray > createFloatInstance( final ImagePlus imp, final int offset ) { return new VirtualStackImageLoader< FloatType, VolatileFloatType, VolatileFloatArray >( - imp, new VirtualStackVolatileFloatArrayLoader( imp ), new FloatType(), new VolatileFloatType() ) + imp, new VirtualStackVolatileFloatArrayLoader( imp ), new FloatType(), new VolatileFloatType(), offset ) { @Override protected void linkType( final CachedCellImg< FloatType, VolatileFloatArray > img ) @@ -81,9 +87,14 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte } public static VirtualStackImageLoader< UnsignedShortType, VolatileUnsignedShortType, VolatileShortArray > createUnsignedShortInstance( final ImagePlus imp ) + { + return createUnsignedShortInstance( imp, 0 ); + } + + public static VirtualStackImageLoader< UnsignedShortType, VolatileUnsignedShortType, VolatileShortArray > createUnsignedShortInstance( final ImagePlus imp, final int offset ) { return new VirtualStackImageLoader< UnsignedShortType, VolatileUnsignedShortType, VolatileShortArray >( - imp, new VirtualStackVolatileShortArrayLoader( imp ), new UnsignedShortType(), new VolatileUnsignedShortType() ) + imp, new VirtualStackVolatileShortArrayLoader( imp ), new UnsignedShortType(), new VolatileUnsignedShortType(), offset ) { @Override protected void linkType( final CachedCellImg< UnsignedShortType, VolatileShortArray > img ) @@ -100,9 +111,14 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte } public static VirtualStackImageLoader< UnsignedByteType, VolatileUnsignedByteType, VolatileByteArray > createUnsignedByteInstance( final ImagePlus imp ) + { + return createUnsignedByteInstance( imp, 0 ); + } + + public static VirtualStackImageLoader< UnsignedByteType, VolatileUnsignedByteType, VolatileByteArray > createUnsignedByteInstance( final ImagePlus imp, final int offset ) { return new VirtualStackImageLoader< UnsignedByteType, VolatileUnsignedByteType, VolatileByteArray >( - imp, new VirtualStackVolatileByteArrayLoader( imp ), new UnsignedByteType(), new VolatileUnsignedByteType() ) + imp, new VirtualStackVolatileByteArrayLoader( imp ), new UnsignedByteType(), new VolatileUnsignedByteType(), offset ) { @Override protected void linkType( final CachedCellImg< UnsignedByteType, VolatileByteArray > img ) @@ -119,9 +135,14 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte } public static VirtualStackImageLoader< ARGBType, VolatileARGBType, VolatileIntArray > createARGBInstance( final ImagePlus imp ) + { + return createARGBInstance( imp, 0 ); + } + + public static VirtualStackImageLoader< ARGBType, VolatileARGBType, VolatileIntArray > createARGBInstance( final ImagePlus imp, final int offset ) { return new VirtualStackImageLoader< ARGBType, VolatileARGBType, VolatileIntArray >( - imp, new VirtualStackVolatileARGBArrayLoader( imp ), new ARGBType(), new VolatileARGBType() ) + imp, new VirtualStackVolatileARGBArrayLoader( imp ), new ARGBType(), new VolatileARGBType(), offset ) { @Override protected void linkType( final CachedCellImg< ARGBType, VolatileIntArray > img ) @@ -149,18 +170,23 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte private final int[] cellDimensions; - private final ArrayList< SetupImgLoader > setupImgLoaders; + private final HashMap< Integer, SetupImgLoader > setupImgLoaders; - protected VirtualStackImageLoader( final ImagePlus imp, final CacheArrayLoader< A > loader, final T type, final V volatileType ) + protected VirtualStackImageLoader( final ImagePlus imp, final CacheArrayLoader< A > loader, final T type, final V volatileType, int setupOffset ) { this.loader = loader; dimensions = new long[] { imp.getWidth(), imp.getHeight(), imp.getNSlices() }; cellDimensions = new int[] { imp.getWidth(), imp.getHeight(), 1 }; final int numSetups = imp.getNChannels(); cache = new VolatileGlobalCellCache( 1, 1 ); - setupImgLoaders = new ArrayList<>(); + setupImgLoaders = new HashMap<>(); for ( int setupId = 0; setupId < numSetups; ++setupId ) - setupImgLoaders.add( new SetupImgLoader( setupId, type, volatileType ) ); + setupImgLoaders.put( setupOffset + setupId, new SetupImgLoader( setupId, type, volatileType ) ); + } + + protected VirtualStackImageLoader( final ImagePlus imp, final CacheArrayLoader< A > loader, final T type, final V volatileType ) + { + this( imp, loader, type, volatileType, 0 ); } protected abstract void linkType( CachedCellImg< T, A > img );