Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit 083cf52

Browse files
committed
More converters and move ImageJ related code to net.imagej
1 parent aabc691 commit 083cf52

10 files changed

Lines changed: 358 additions & 148 deletions

src/main/java/net/imagej/notebook/DefaultImageJNotebookService.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ public class DefaultImageJNotebookService extends AbstractService implements
8080
private OpService ops;
8181

8282
@Override
83-
public <T extends RealType<T>> Object display(
83+
public <T extends RealType<T>> Object RAIToPNG(
8484
final RandomAccessibleInterval<T> source, //
8585
final int xAxis, final int yAxis, final int cAxis, //
8686
final ValueScaling scaling, final long... pos) {
87-
87+
8888
final IntervalView<T> image = ops.transform().zeroMin(source);
8989

9090
final int w = xAxis >= 0 ? (int) image.dimension(xAxis) : 1;
@@ -114,7 +114,7 @@ public <T extends RealType<T>> Object display(
114114
final ColorTable8 lut = c == 1
115115
? //
116116
ColorTables.GRAYS : ColorTables.getDefaultColorTable(i);
117-
converters.add(new RealLUTConverter<T>(min, max, lut));
117+
converters.add(new RealLUTConverter<>(min, max, lut));
118118
}
119119
final CompositeXYProjector<T> proj = new CompositeXYProjector<>(image,
120120
target, converters, cAxis);
@@ -141,8 +141,8 @@ public <T extends RealType<T>> Object display(
141141
@SuppressWarnings("unchecked") final RandomAccessibleInterval<T>... images) {
142142
// Count the actual number of image dimensions.
143143
int numDims = 0;
144-
for (int i = 0; i < images.length; i++) {
145-
numDims = Math.max(numDims, images[i].numDimensions());
144+
for (RandomAccessibleInterval<T> image : images) {
145+
numDims = Math.max(numDims, image.numDimensions());
146146
}
147147

148148
// Pad any missing grid dimensions.

src/main/java/net/imagej/notebook/ImageJNotebookService.java

Lines changed: 114 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
* POSSIBILITY OF SUCH DAMAGE.
2828
* #L%
2929
*/
30-
3130
package net.imagej.notebook;
3231

3332
import net.imagej.Dataset;
@@ -39,135 +38,130 @@
3938
import net.imglib2.type.numeric.RealType;
4039

4140
/**
42-
* Interface for services which provide handy methods for working with
43-
* scientific notebook software (e.g.,
41+
* Interface for services which provide handy methods for working with scientific notebook software
42+
* (e.g.,
4443
* <a href="http://beakernotebook.com/">Beaker Notebook</a>).
4544
*
4645
* @author Curtis Rueden
4746
*/
4847
public interface ImageJNotebookService extends ImageJService {
4948

50-
/** Strategy to use for scaling the image intensity values. */
51-
enum ValueScaling {
52-
/**
53-
* Scales the display according to a "best effort": "narrow" types with
54-
* few sample values (e.g., {@code bit}, {@code uint2}, {@code uint4} and
55-
* {@code uint8}) are scaled according to the {@code FULL} strategy,
56-
* whereas "wide" types with many possible values (e.g., {@code uint16},
57-
* {@code float32} and {@code float64}) are scaled according to the
58-
* {@code DATA} strategy.
59-
* <p>
60-
* That rationale is that people are accustomed to seeing narrow image
61-
* types rendered across the full range, whereas wide image types
62-
* typically do not empass the entire range of the type and rendering them
63-
* as such results in image which appear all or mostly black or gray.
64-
* </p>
65-
*/
66-
AUTO,
67-
68-
/**
69-
* Scales the display to match the bounds of the data type. For example,
70-
* {@code uint8} will be scaled to 0-255, regardless of the actual data
71-
* values.
72-
*/
73-
FULL,
74-
75-
/**
76-
* Scales the display to match the actual min and max values of the data.
77-
* For example, a {@code uint16} dataset with sample values ranging
78-
* between 139 and 3156 will map 139 to minimum intensity and 3156 to
79-
* maximum intensity.
80-
*/
81-
DATA
82-
}
49+
/**
50+
* Strategy to use for scaling the image intensity values.
51+
*/
52+
enum ValueScaling {
53+
/**
54+
* Scales the RAIToPNG according to a "best effort": "narrow" types with few sample values
55+
(e.g., {@code bit}, {@code uint2}, {@code uint4} and {@code uint8}) are scaled according
56+
* to the {@code FULL} strategy, whereas "wide" types with many possible values (e.g.,
57+
* {@code uint16}, {@code float32} and {@code float64}) are scaled according to the
58+
* {@code DATA} strategy.
59+
* <p>
60+
* That rationale is that people are accustomed to seeing narrow image types rendered across
61+
* the full range, whereas wide image types typically do not empass the entire range of the
62+
* type and rendering them as such results in image which appear all or mostly black or
63+
* gray.
64+
* </p>
65+
*/
66+
AUTO,
67+
/**
68+
* Scales the RAIToPNG to match the bounds of the data type. For example, {@code uint8} will
69+
* be scaled to 0-255, regardless of the actual data values.
70+
*/
71+
FULL,
72+
/**
73+
* Scales the RAIToPNG to match the actual min and max values of the data. For example, a
74+
* {@code uint16} dataset with sample values ranging between 139 and 3156 will map 139 to
75+
* minimum intensity and 3156 to maximum intensity.
76+
*/
77+
DATA
78+
}
8379

84-
/**
85-
* Converts the given image to a form renderable by scientific notebooks.
86-
*
87-
* @param source The image to render.
88-
* @return an object that the notebook knows how to draw onscreen.
89-
*/
90-
@SuppressWarnings({ "rawtypes", "unchecked" })
91-
default Object display(final Dataset source) {
92-
return display((Img) source, //
93-
source.dimensionIndex(Axes.X), //
94-
source.dimensionIndex(Axes.Y), //
95-
source.dimensionIndex(Axes.CHANNEL), ValueScaling.AUTO);
96-
}
80+
/**
81+
* Converts the given image to a form renderable by scientific notebooks.
82+
*
83+
* @param source The image to render.
84+
* @return an object that the notebook knows how to draw onscreen.
85+
*/
86+
@SuppressWarnings({"rawtypes", "unchecked"})
87+
default Object display(final Dataset source) {
88+
return RAIToPNG((Img) source, //
89+
source.dimensionIndex(Axes.X), //
90+
source.dimensionIndex(Axes.Y), //
91+
source.dimensionIndex(Axes.CHANNEL), ValueScaling.AUTO);
92+
}
9793

98-
/**
99-
* Converts the given image to a form renderable by scientific notebooks.
100-
*
101-
* @param source The image to render.
102-
* @return an object that the notebook knows how to draw onscreen.
103-
*/
104-
default <T extends RealType<T>> Object display(
105-
final RandomAccessibleInterval<T> source)
106-
{
107-
// NB: Assume <=3 samples in the 3rd dimension means channels. Of course,
108-
// we have no metadata with a vanilla RAI, but this is a best guess;
109-
// 3rd dimensions with >3 samples are probably something like Z or time.
110-
final int cAxis = //
111-
source.numDimensions() > 2 && source.dimension(2) <= 3 ? 2 : -1;
94+
/**
95+
* Converts the given image to a form renderable by scientific notebooks.
96+
*
97+
* @param <T>
98+
* @param source The image to render.
99+
* @return an object that the notebook knows how to draw onscreen.
100+
*/
101+
default <T extends RealType<T>> Object display(
102+
final RandomAccessibleInterval<T> source) {
103+
// NB: Assume <=3 samples in the 3rd dimension means channels. Of course,
104+
// we have no metadata with a vanilla RAI, but this is a best guess;
105+
// 3rd dimensions with >3 samples are probably something like Z or time.
106+
final int cAxis
107+
= //
108+
source.numDimensions() > 2 && source.dimension(2) <= 3 ? 2 : -1;
112109

113-
return display(source, 0, 1, cAxis, ValueScaling.AUTO);
114-
}
110+
return RAIToPNG(source, 0, 1, cAxis, ValueScaling.AUTO);
111+
}
115112

116-
/**
117-
* Converts the given image to a form renderable by scientific notebooks.
118-
*
119-
* @param source The image to render.
120-
* @param xAxis The image dimension to use for the X axis.
121-
* @param yAxis The image dimension to use for the Y axis.
122-
* @param cAxis The image dimension to use for compositing multiple channels,
123-
* or -1 for no compositing.
124-
* @param scaling Value scaling strategy; see {@link ValueScaling}.
125-
* @param pos Dimensional position of the image. Passing null or the empty
126-
* array will display the default (typically the first) position.
127-
* @return an object that the notebook knows how to draw onscreen.
128-
*/
129-
<T extends RealType<T>> Object display(RandomAccessibleInterval<T> source,
130-
int xAxis, int yAxis, int cAxis, ValueScaling scaling, long... pos);
113+
/**
114+
* Converts the given image to a form renderable by scientific notebooks.
115+
*
116+
* @param <T>
117+
* @param source The image to render.
118+
* @param xAxis The image dimension to use for the X axis.
119+
* @param yAxis The image dimension to use for the Y axis.
120+
* @param cAxis The image dimension to use for compositing multiple channels, or -1 for no
121+
* compositing.
122+
* @param scaling Value scaling strategy; see {@link ValueScaling}.
123+
* @param pos Dimensional position of the image. Passing null or the empty array will RAIToPNG
124+
the default (typically the first) position.
125+
* @return an object that the notebook knows how to draw onscreen.
126+
*/
127+
<T extends RealType<T>> Object RAIToPNG(RandomAccessibleInterval<T> source,
128+
int xAxis, int yAxis, int cAxis, ValueScaling scaling, long... pos);
131129

132-
/**
133-
* Organizes the given list of images into an N-dimensional mosaic.
134-
* <p>
135-
* For example, passing a grid layout of {2, 2} with four images {A, B, C, D}
136-
* will result in them being laid out along the first two axes (let's call
137-
* them X and Y) in a 2 x 2 grid:
138-
*
139-
* <pre>
140-
* AB
141-
* CD
142-
* </pre>
143-
* </p>
144-
* <p>
145-
* The images do not need to be of equal size; images will be padded along
146-
* each dimension as needed so that everything lines up in a grid. In the
147-
* example above, if A and C have different widths, then the first column will
148-
* be as wide as the wider of the two. Same for the second column with images
149-
* B and D. If A and B have different heights, than the first row will be as
150-
* tall as the taller of the two. And same for the second row with images C
151-
* and D.
152-
* </p>
153-
* <p>
154-
* Normally, the number of grid cells (i.e., the product of the grid
155-
* dimensions) should match the given number of images. However, the algorithm
156-
* handles a mismatch in either direction. If the number of grid cells is less
157-
* than the number of images, than the excess images are discarded&mdash;i.e.,
158-
* they will not appear anywhere in the mosaic. On the other hand, if the
159-
* number of grid cells exceeds the given number of images, then some grid
160-
* cells will be empty. The cells are filled along the first dimension
161-
* fastest, so e.g. a grid layout of {2, 3, 2} will fill as follows: 000, 100,
162-
* 010, 110, 020, 120, 001, 101, 011, 111, 021, 121.
163-
* </p>
164-
*
165-
* @param gridLayout Dimensions of the grid.
166-
* @param images Images to combine into the mosaic.
167-
* @return A single mosaic image, laid out as specified.
168-
*/
169-
<T extends RealType<T> & NativeType<T>> RandomAccessibleInterval<T> mosaic(
170-
final int[] gridLayout,
171-
@SuppressWarnings("unchecked") final RandomAccessibleInterval<T>... images);
130+
/**
131+
* Organizes the given list of images into an N-dimensional mosaic.
132+
* <p>
133+
* For example, passing a grid layout of {2, 2} with four images {A, B, C, D} will result in
134+
* them being laid out along the first two axes (let's call them X and Y) in a 2 x 2 grid:
135+
*
136+
* <pre>
137+
* AB
138+
* CD
139+
* </pre>
140+
* </p>
141+
* <p>
142+
* The images do not need to be of equal size; images will be padded along each dimension as
143+
* needed so that everything lines up in a grid. In the example above, if A and C have different
144+
* widths, then the first column will be as wide as the wider of the two. Same for the second
145+
* column with images B and D. If A and B have different heights, than the first row will be as
146+
* tall as the taller of the two. And same for the second row with images C and D.
147+
* </p>
148+
* <p>
149+
* Normally, the number of grid cells (i.e., the product of the grid dimensions) should match
150+
* the given number of images. However, the algorithm handles a mismatch in either direction. If
151+
* the number of grid cells is less than the number of images, than the excess images are
152+
* discarded&mdash;i.e., they will not appear anywhere in the mosaic. On the other hand, if the
153+
* number of grid cells exceeds the given number of images, then some grid cells will be empty.
154+
* The cells are filled along the first dimension fastest, so e.g. a grid layout of {2, 3, 2}
155+
* will fill as follows: 000, 100, 010, 110, 020, 120, 001, 101, 011, 111, 021, 121.
156+
* </p>
157+
*
158+
* @param <T>
159+
* @param gridLayout Dimensions of the grid.
160+
* @param images Images to combine into the mosaic.
161+
* @return A single mosaic image, laid out as specified.
162+
*/
163+
<T extends RealType<T> & NativeType<T>> RandomAccessibleInterval<T> mosaic(
164+
final int[] gridLayout,
165+
@SuppressWarnings("unchecked") final RandomAccessibleInterval<T>... images);
172166

173167
}

src/main/java/org/scijava/notebook/converter/DatasetToPNGNotebookConverter.java renamed to src/main/java/net/imagej/notebook/converter/DatasetToPNGNotebookConverter.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.scijava.notebook.converter;
16+
package net.imagej.notebook.converter;
1717

1818
import net.imagej.Dataset;
1919
import net.imagej.axis.Axes;
20-
import net.imagej.notebook.DefaultImageJNotebookService;
2120
import net.imagej.notebook.ImageJNotebookService;
2221
import net.imglib2.img.Img;
2322
import org.scijava.Priority;
2423
import org.scijava.convert.Converter;
24+
import org.scijava.notebook.converter.NotebookOutputConverter;
2525
import org.scijava.notebook.converter.ouput.PNGImageNotebookOutput;
2626
import org.scijava.plugin.Parameter;
2727
import org.scijava.plugin.Plugin;
@@ -31,8 +31,8 @@ public class DatasetToPNGNotebookConverter<O extends Dataset>
3131
extends NotebookOutputConverter<O, PNGImageNotebookOutput> {
3232

3333
@Parameter
34-
private DefaultImageJNotebookService ijnb;
35-
34+
private ImageJNotebookService ijnb;
35+
3636
@Override
3737
public Class getInputType() {
3838
return Dataset.class;
@@ -45,15 +45,15 @@ public Class getOutputType() {
4545

4646
@Override
4747
public PNGImageNotebookOutput convert(Object object) {
48-
48+
4949
Dataset source = (Dataset) object;
50-
51-
String base64Image = (String) ijnb.display((Img) source, //
50+
51+
String base64Image = (String) ijnb.RAIToPNG((Img) source, //
5252
source.dimensionIndex(Axes.X),
5353
source.dimensionIndex(Axes.Y),
5454
source.dimensionIndex(Axes.CHANNEL),
5555
ImageJNotebookService.ValueScaling.AUTO);
56-
56+
5757
return new PNGImageNotebookOutput(PNGImageNotebookOutput.getMimeType(), base64Image);
5858
}
5959

0 commit comments

Comments
 (0)