Skip to content

Commit a283f3f

Browse files
committed
Add converters from AbstractPlot to ImagePlus and Img
1 parent ea7970f commit a283f3f

5 files changed

Lines changed: 300 additions & 0 deletions

File tree

pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,5 +128,14 @@
128128
<groupId>org.jfree</groupId>
129129
<artifactId>jfreechart</artifactId>
130130
</dependency>
131+
<dependency>
132+
<groupId>net.imglib2</groupId>
133+
<artifactId>imglib2-ij</artifactId>
134+
</dependency>
135+
<dependency>
136+
<groupId>junit</groupId>
137+
<artifactId>junit</artifactId>
138+
<scope>test</scope>
139+
</dependency>
131140
</dependencies>
132141
</project>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package net.imagej.plot.convert;
2+
3+
import ij.IJ;
4+
import ij.ImagePlus;
5+
import net.imagej.plot.AbstractPlot;
6+
import org.jfree.chart.JFreeChart;
7+
import org.scijava.Priority;
8+
import org.scijava.convert.AbstractConverter;
9+
import org.scijava.convert.ConversionRequest;
10+
import org.scijava.convert.ConvertService;
11+
import org.scijava.convert.Converter;
12+
import org.scijava.plugin.Parameter;
13+
import org.scijava.plugin.Plugin;
14+
15+
import java.awt.geom.Rectangle2D;
16+
import java.awt.image.BufferedImage;
17+
18+
/**
19+
* Converter plugin, that converts an {@link AbstractPlot} to {@link ImagePlus}.
20+
*
21+
* @author Matthias Arzt
22+
* @see ConvertService
23+
*/
24+
@Plugin(type = Converter.class, priority = Priority.NORMAL_PRIORITY)
25+
public class PlotToImagePlusConverter extends AbstractConverter<AbstractPlot, ImagePlus> {
26+
27+
@Parameter
28+
ConvertService convertService;
29+
30+
@Override
31+
public boolean canConvert(ConversionRequest request) {
32+
return ImagePlus.class.equals(request.destClass()) &&
33+
AbstractPlot.class.isAssignableFrom(request.sourceClass()) &&
34+
convertService.supports(new ConversionRequest(
35+
request.sourceObject(), request.sourceType(), JFreeChart.class));
36+
}
37+
38+
@Override
39+
public <T> T convert(Object o, Class<T> aClass) {
40+
if(o instanceof AbstractPlot && ImagePlus.class.equals(aClass)) {
41+
@SuppressWarnings("unchecked")
42+
T t = (T) toImagePlus((AbstractPlot) o);
43+
return t;
44+
}
45+
return null;
46+
}
47+
48+
private ImagePlus toImagePlus(AbstractPlot plot) {
49+
JFreeChart chart = convertService.convert(plot, JFreeChart.class);
50+
ImagePlus imp = IJ.createImage(plot.getTitle(), "RGB", plot.getPreferredWidth(), plot.getPreferredHeight(), 1);
51+
BufferedImage image = imp.getBufferedImage();
52+
chart.draw(image.createGraphics(), new Rectangle2D.Float(0, 0, imp.getWidth(), imp.getHeight()));
53+
imp.setImage(image);
54+
return imp;
55+
}
56+
57+
@Override
58+
public Class<ImagePlus> getOutputType() {
59+
return ImagePlus.class;
60+
}
61+
62+
@Override
63+
public Class<AbstractPlot> getInputType() {
64+
return AbstractPlot.class;
65+
}
66+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package net.imagej.plot.convert;
2+
3+
import ij.ImagePlus;
4+
import net.imagej.plot.AbstractPlot;
5+
import net.imglib2.img.Img;
6+
import net.imglib2.img.display.imagej.ImageJFunctions;
7+
import org.scijava.Priority;
8+
import org.scijava.convert.AbstractConverter;
9+
import org.scijava.convert.ConversionRequest;
10+
import org.scijava.convert.ConvertService;
11+
import org.scijava.convert.Converter;
12+
import org.scijava.plugin.Parameter;
13+
import org.scijava.plugin.Plugin;
14+
15+
/**
16+
* Converter plugin, that converts {@link AbstractPlot} to {@link Img}.
17+
*
18+
* @author Matthias Arzt
19+
* @see ConvertService
20+
*/
21+
@Plugin(type = Converter.class, priority = Priority.NORMAL_PRIORITY)
22+
public class PlotToImgConverter extends AbstractConverter<AbstractPlot, Img> {
23+
24+
@Parameter
25+
ConvertService convertService;
26+
27+
@Override
28+
public boolean canConvert(ConversionRequest request) {
29+
return Img.class.equals(request.destClass()) &&
30+
AbstractPlot.class.isAssignableFrom(request.sourceClass()) &&
31+
convertService.supports(new ConversionRequest(
32+
request.sourceObject(), request.sourceType(), ImagePlus.class));
33+
}
34+
35+
@Override
36+
public <T> T convert(Object o, Class<T> aClass) {
37+
ImagePlus imp = convertService.convert(o, ImagePlus.class);
38+
@SuppressWarnings("unchecked")
39+
T t = (T) ImageJFunctions.wrapRGBA(imp);
40+
return t;
41+
}
42+
43+
@Override
44+
public Class<Img> getOutputType() {
45+
return Img.class;
46+
}
47+
48+
@Override
49+
public Class<AbstractPlot> getInputType() {
50+
return AbstractPlot.class;
51+
}
52+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package net.imagej.plot;
2+
3+
import ij.ImagePlus;
4+
import net.imglib2.img.Img;
5+
import net.imglib2.img.display.imagej.ImageJFunctions;
6+
import net.imglib2.type.numeric.ARGBType;
7+
import org.scijava.Context;
8+
import org.scijava.convert.ConvertService;
9+
import org.scijava.plugin.Parameter;
10+
11+
import java.util.List;
12+
import java.util.stream.Collectors;
13+
import java.util.stream.IntStream;
14+
15+
/**
16+
* Demonstrates how to convert an {@link AbstractPlot} to {@link Img} and {@link ImagePlus}.
17+
*
18+
* @author Matthias Arzt
19+
*/
20+
public class PlotToImageDemo {
21+
22+
@Parameter
23+
PlotService plotService;
24+
25+
@Parameter
26+
ConvertService convertService;
27+
28+
private void run() {
29+
XYPlot plot = getXyPlot();
30+
31+
// convert to Img
32+
Img<ARGBType> img = convertService.convert(plot, Img.class);
33+
ImageJFunctions.show(img);
34+
35+
// convert to ImagePlus
36+
ImagePlus imagePlus = convertService.convert(plot, ImagePlus.class);
37+
imagePlus.show();
38+
}
39+
40+
private XYPlot getXyPlot() {
41+
XYPlot plot = plotService.newXYPlot();
42+
XYSeries series = plot.addXYSeries();
43+
List<Double> xs = IntStream.rangeClosed(0, 100).mapToObj(x -> (double) x * 2. * Math.PI / 100.).collect(Collectors.toList());
44+
List<Double> ys = xs.stream().map(Math::sin).collect(Collectors.toList());
45+
series.setValues( xs, ys );
46+
return plot;
47+
}
48+
49+
public static void main(String... args) {
50+
PlotToImageDemo demo = new PlotToImageDemo();
51+
new Context().inject(demo);
52+
demo.run();
53+
}
54+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package net.imagej.plot.convert;
2+
3+
import ij.ImagePlus;
4+
import net.imagej.plot.AbstractPlot;
5+
import net.imagej.plot.CategoryChart;
6+
import net.imagej.plot.PlotService;
7+
import net.imglib2.img.Img;
8+
import net.imglib2.type.numeric.ARGBType;
9+
import org.junit.Test;
10+
import org.scijava.Context;
11+
import org.scijava.convert.ConvertService;
12+
13+
import java.lang.reflect.Type;
14+
15+
import static org.junit.Assert.assertEquals;
16+
import static org.junit.Assert.assertFalse;
17+
import static org.junit.Assert.assertTrue;
18+
19+
/**
20+
* Tests {@link PlotToImgConverter} and {@link PlotToImagePlusConverter}
21+
*
22+
* @author Matthias Arzt
23+
*/
24+
public class PlotToImageConverterTest {
25+
26+
private final Context context = new Context(PlotService.class, ConvertService.class);
27+
28+
private final ConvertService convertService = context.service(ConvertService.class);
29+
30+
private final PlotService plotService = context.service(PlotService.class);
31+
32+
@Test
33+
public void testCanConvertCategoryChartToImagePlus() {
34+
testCanConvertCategoryChartTo(ImagePlus.class);
35+
}
36+
37+
@Test
38+
public void testCanConvertCategoryChartToImg() {
39+
testCanConvertCategoryChartTo(Img.class);
40+
}
41+
42+
@Test
43+
public void testWontConvertAbstractPlotToImagePlus() {
44+
testWontConvertAbstractPlotTo(ImagePlus.class);
45+
}
46+
47+
@Test
48+
public void testWontConvertAbstractPlotToImg() {
49+
testWontConvertAbstractPlotTo(Img.class);
50+
}
51+
52+
public void testCanConvertCategoryChartTo(Class<?> destClass) {
53+
CategoryChart<String> chart = plotService.newCategoryChart(String.class);
54+
assertTrue(convertService.supports(chart, destClass));
55+
assertTrue(convertService.supports(chart, (Type) destClass));
56+
}
57+
58+
public void testWontConvertAbstractPlotTo(Class<?> destClass) {
59+
AbstractPlot ap = new CustomAbstractPlot();
60+
assertFalse(convertService.supports(ap, destClass));
61+
assertFalse(convertService.supports(ap, (Type) destClass));
62+
}
63+
64+
@Test
65+
public void testConversionToImagePlus() {
66+
// setup
67+
CategoryChart chart = plotService.newCategoryChart(String.class);
68+
chart.setTitle("Hello World!");
69+
chart.setPreferredSize(12,23);
70+
// process
71+
ImagePlus imp = convertService.convert(chart, ImagePlus.class);
72+
// test
73+
assertEquals(chart.getTitle(), imp.getTitle());
74+
assertEquals(chart.getPreferredWidth(), imp.getWidth());
75+
assertEquals(chart.getPreferredHeight(), imp.getHeight());
76+
}
77+
78+
@Test
79+
public void testConversionToImg() {
80+
// setup
81+
CategoryChart chart = plotService.newCategoryChart(String.class);
82+
chart.setTitle("Hello World!");
83+
chart.setPreferredSize(12,23);
84+
// process
85+
Img<ARGBType> img = convertService.convert(chart, Img.class);
86+
// test
87+
assertEquals(chart.getPreferredWidth(), img.max(0) + 1);
88+
assertEquals(chart.getPreferredHeight(), img.max(1) + 1);
89+
}
90+
91+
// -- Helper class --
92+
93+
class CustomAbstractPlot implements AbstractPlot {
94+
@Override
95+
public void setTitle(String title) {
96+
97+
}
98+
99+
@Override
100+
public String getTitle() {
101+
return null;
102+
}
103+
104+
@Override
105+
public void setPreferredSize(int width, int height) {
106+
107+
}
108+
109+
@Override
110+
public int getPreferredWidth() {
111+
return 0;
112+
}
113+
114+
@Override
115+
public int getPreferredHeight() {
116+
return 0;
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)