Skip to content

Commit f0d8ef3

Browse files
committed
Partition ImagePlus->Img, ImgPlus
Only one of these should live here forever so this change will make that easier.
1 parent 8c041e6 commit f0d8ef3

11 files changed

+352
-344
lines changed
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
/*
2+
* #%L
3+
* ImgLib2: a general-purpose, multidimensional image processing library.
4+
* %%
5+
* Copyright (C) 2009 - 2025 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld,
6+
* John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke,
7+
* Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner,
8+
* Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert,
9+
* Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin,
10+
* Jean-Yves Tinevez and Michael Zinsmaier.
11+
* %%
12+
* Redistribution and use in source and binary forms, with or without
13+
* modification, are permitted provided that the following conditions are met:
14+
*
15+
* 1. Redistributions of source code must retain the above copyright notice,
16+
* this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright notice,
18+
* this list of conditions and the following disclaimer in the documentation
19+
* and/or other materials provided with the distribution.
20+
*
21+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
25+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
* #L%
33+
*/
34+
35+
package net.imglib2.imagej;
36+
37+
import ij.ImagePlus;
38+
import net.imglib2.Cursor;
39+
import net.imglib2.cache.Cache;
40+
import net.imglib2.cache.ref.SoftRefLoaderCache;
41+
import net.imglib2.converter.Converter;
42+
import net.imglib2.imagej.imageplus.*;
43+
import net.imglib2.img.Img;
44+
import net.imglib2.img.basictypeaccess.array.ArrayDataAccess;
45+
import net.imglib2.img.planar.PlanarImg;
46+
import net.imglib2.type.Type;
47+
import net.imglib2.type.numeric.ARGBType;
48+
import net.imglib2.type.numeric.ComplexType;
49+
import net.imglib2.type.numeric.integer.UnsignedByteType;
50+
import net.imglib2.type.numeric.integer.UnsignedIntType;
51+
import net.imglib2.type.numeric.integer.UnsignedShortType;
52+
import net.imglib2.type.numeric.real.FloatType;
53+
54+
import java.util.AbstractList;
55+
import java.util.concurrent.ExecutionException;
56+
import java.util.function.Function;
57+
58+
/**
59+
* Provides convenience functions to wrap ImageJ 1.x data structures as ImgLib2
60+
* ones.
61+
*
62+
*
63+
* @author Stephan Preibisch
64+
* @author Stephan Saalfeld
65+
* @author Matthias Arzt
66+
*/
67+
public class ImagePlusToImg
68+
{
69+
70+
public static PlanarImg< ?, ? > wrap( final ImagePlus imp )
71+
{
72+
switch ( imp.getType() )
73+
{
74+
case ImagePlus.GRAY8:
75+
return wrapByte( imp );
76+
case ImagePlus.GRAY16:
77+
return wrapShort( imp );
78+
case ImagePlus.GRAY32:
79+
return wrapFloat( imp );
80+
case ImagePlus.COLOR_RGB:
81+
return wrapRGBA( imp );
82+
default:
83+
throw new RuntimeException( "Only 8, 16, 32-bit and RGB supported!" );
84+
}
85+
}
86+
87+
public static PlanarImg< UnsignedByteType, ? > wrapByte(final ImagePlus imp )
88+
{
89+
if ( imp.getType() != ImagePlus.GRAY8 )
90+
return null;
91+
92+
final ByteImagePlus< UnsignedByteType > container = new ByteImagePlus<>( imp );
93+
94+
// create a Type that is linked to the container
95+
final UnsignedByteType linkedType = new UnsignedByteType( container );
96+
97+
// pass it to the NativeContainer
98+
container.setLinkedType( linkedType );
99+
100+
return container;
101+
}
102+
103+
public static PlanarImg< UnsignedShortType, ? > wrapShort(final ImagePlus imp )
104+
{
105+
if ( imp.getType() != ImagePlus.GRAY16 )
106+
return null;
107+
108+
final ShortImagePlus< UnsignedShortType > container = new ShortImagePlus<>( imp );
109+
110+
// create a Type that is linked to the container
111+
final UnsignedShortType linkedType = new UnsignedShortType( container );
112+
113+
// pass it to the DirectAccessContainer
114+
container.setLinkedType( linkedType );
115+
116+
return container;
117+
}
118+
119+
public static PlanarImg< UnsignedIntType, ? > wrapInt(final ImagePlus imp )
120+
{
121+
if( imp.getType() != ImagePlus.COLOR_RGB )
122+
return null;
123+
124+
final IntImagePlus< UnsignedIntType > container = new IntImagePlus<>( imp );
125+
126+
// create a Type that is linked to the container
127+
final UnsignedIntType linkedType = new UnsignedIntType( container );
128+
129+
// pass it to the DirectAccessContainer
130+
container.setLinkedType( linkedType );
131+
132+
return container;
133+
}
134+
135+
public static PlanarImg< ARGBType, ? > wrapRGBA( final ImagePlus imp )
136+
{
137+
if ( imp.getType() != ImagePlus.COLOR_RGB )
138+
return null;
139+
140+
final IntImagePlus< ARGBType > container = new IntImagePlus<>( imp );
141+
142+
// create a Type that is linked to the container
143+
final ARGBType linkedType = new ARGBType( container );
144+
145+
// pass it to the DirectAccessContainer
146+
container.setLinkedType( linkedType );
147+
148+
return container;
149+
}
150+
151+
public static PlanarImg< FloatType, ? > wrapFloat(final ImagePlus imp )
152+
{
153+
if ( imp.getType() != ImagePlus.GRAY32 )
154+
return null;
155+
156+
final FloatImagePlus< FloatType > container = new FloatImagePlus<>( imp );
157+
158+
// create a Type that is linked to the container
159+
final FloatType linkedType = new FloatType( container );
160+
161+
// pass it to the DirectAccessContainer
162+
container.setLinkedType( linkedType );
163+
164+
return container;
165+
}
166+
167+
public static PlanarImg< FloatType, ? > convertFloat( final ImagePlus imp )
168+
{
169+
170+
switch ( imp.getType() )
171+
{
172+
case ImagePlus.GRAY8:
173+
return convertToFloat( wrapByte( imp ), new NumberToFloatConverter< UnsignedByteType >() );
174+
case ImagePlus.GRAY16:
175+
return convertToFloat( wrapShort( imp ), new NumberToFloatConverter< UnsignedShortType >() );
176+
case ImagePlus.GRAY32:
177+
return wrapFloat( imp );
178+
case ImagePlus.COLOR_RGB:
179+
return convertToFloat( wrapRGBA( imp ), new ARGBtoFloatConverter() );
180+
default:
181+
throw new RuntimeException( "Only 8, 16, 32-bit and RGB supported!" );
182+
}
183+
}
184+
185+
static private class ARGBtoFloatConverter implements Converter< ARGBType, FloatType >
186+
{
187+
/** Luminance times alpha. */
188+
@Override
189+
public void convert( final ARGBType input, final FloatType output )
190+
{
191+
final int v = input.get();
192+
output.setReal( ( ( v >> 24 ) & 0xff ) * ( ( ( v >> 16 ) & 0xff ) * 0.299 + ( ( v >> 8 ) & 0xff ) * 0.587 + ( v & 0xff ) * 0.144 ) );
193+
}
194+
}
195+
196+
static private class NumberToFloatConverter< T extends ComplexType< T > > implements Converter< T, FloatType >
197+
{
198+
@Override
199+
public void convert( final T input, final FloatType output )
200+
{
201+
output.setReal( input.getRealFloat() );
202+
}
203+
}
204+
205+
protected static < T extends Type< T > > PlanarImg< FloatType, ?> convertToFloat(
206+
final Img< T > input, final Converter< T, FloatType > c )
207+
{
208+
final ImagePlusImg< FloatType, ? > output = new ImagePlusImgFactory<>( new FloatType() ).create( input );
209+
210+
final Cursor< T > in = input.cursor();
211+
final Cursor< FloatType > out = output.cursor();
212+
213+
while ( in.hasNext() )
214+
{
215+
in.fwd();
216+
out.fwd();
217+
218+
c.convert( in.get(), out.get() );
219+
}
220+
221+
return output;
222+
}
223+
224+
private static class ImagePlusLoader< A extends ArrayDataAccess< A >> extends AbstractList< A >
225+
{
226+
private final ImagePlus image;
227+
228+
private final Cache< Integer, A > cache;
229+
230+
private final Function< Object, A > arrayFactory;
231+
232+
public ImagePlusLoader( final ImagePlus image, final Function< Object, A > arrayFactory )
233+
{
234+
this.arrayFactory = arrayFactory;
235+
this.image = image;
236+
cache = new SoftRefLoaderCache< Integer, A >().withLoader( this::load );
237+
}
238+
239+
@Override
240+
public A get( final int key )
241+
{
242+
try
243+
{
244+
return cache.get( key );
245+
}
246+
catch ( final ExecutionException e )
247+
{
248+
throw new RuntimeException( e );
249+
}
250+
}
251+
252+
private A load( final Integer key )
253+
{
254+
return arrayFactory.apply( image.getStack().getPixels( key + 1 ) );
255+
}
256+
257+
@Override
258+
public int size()
259+
{
260+
return image.getStackSize();
261+
}
262+
}
263+
264+
//
265+
}

0 commit comments

Comments
 (0)