Skip to content

Commit 6bbd8b1

Browse files
author
clemens-vonschwerin-knime
committed
Support for new python2 extension points added
1 parent 92435ae commit 6bbd8b1

File tree

5 files changed

+275
-2
lines changed

5 files changed

+275
-2
lines changed

org.knime.knip.knimepython/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ Require-Bundle: org.knime.base;bundle-version="2.11.0",
2020
scijava-common;bundle-version="2.37.0",
2121
imagej-common;bundle-version="0.12.1",
2222
scifio-bf-compat;bundle-version="1.11.0",
23-
org.knime.python.nodes;bundle-version="3.0.0"
23+
org.knime.python.nodes;bundle-version="3.0.0",
24+
org.knime.python2;bundle-version="3.3.0"
2425
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
2526
Bundle-ClassPath: .
2627
Export-Package: org.knime.knip.knimepython

org.knime.knip.knimepython/plugin.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,21 @@
3030
path="templates/">
3131
</folder>
3232
</extension>
33+
<extension
34+
point="org.knime.python2.typeextension.knimetopython">
35+
<type
36+
id="org.knime.knip.knimepython.ImgPlus"
37+
java-serializer-factory="org.knime.knip.knimepython2.ImgPlusSerializerFactory"
38+
python-deserializer="py/KNIPImageDeserializer.py">
39+
</type>
40+
</extension>
41+
<extension
42+
point="org.knime.python2.typeextension.pythontoknime">
43+
<type
44+
id="org.knime.knip.knimepython.type2"
45+
java-deserializer-factory="org.knime.knip.knimepython2.ImgPlusDeserializerFactory"
46+
python-serializer="py/KNIPImageSerializer.py"
47+
python-type-identifier="KNIPImage.KNIPImage">
48+
</type>
49+
</extension>
3350
</plugin>

org.knime.knip.knimepython/py/KNIPImage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
class KNIPImage:
33
# data is ndarray
44
def __init__(self, array):
5-
self.array = array
5+
self.array = array
66

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package org.knime.knip.knimepython2;
2+
3+
import java.io.IOException;
4+
5+
import org.knime.core.data.DataCell;
6+
import org.knime.core.data.filestore.FileStoreFactory;
7+
import org.knime.knip.base.data.img.ImgPlusCell;
8+
import org.knime.knip.base.data.img.ImgPlusCellFactory;
9+
import org.knime.knip.io.ScifioGateway;
10+
import org.knime.python2.typeextension.Deserializer;
11+
import org.knime.python2.typeextension.DeserializerFactory;
12+
13+
import io.scif.Format;
14+
import io.scif.FormatException;
15+
import io.scif.Metadata;
16+
import io.scif.Parser;
17+
import io.scif.Reader;
18+
import io.scif.config.SCIFIOConfig;
19+
import io.scif.img.ImgOpener;
20+
import io.scif.io.RandomAccessInputStream;
21+
import net.imagej.ImgPlus;
22+
23+
public class ImgPlusDeserializerFactory extends DeserializerFactory {
24+
25+
/**
26+
* ImgOpener to read ImgPlus from stream
27+
*/
28+
private ImgOpener m_imgOpener;
29+
private SCIFIOConfig m_scifioConfig;
30+
31+
public ImgPlusDeserializerFactory() {
32+
super(ImgPlusCell.TYPE);
33+
m_imgOpener = new ImgOpener(ScifioGateway.getSCIFIO().context());
34+
m_scifioConfig = new SCIFIOConfig();
35+
m_scifioConfig.groupableSetGroupFiles(false);
36+
m_scifioConfig.imgOpenerSetComputeMinMax(false);
37+
}
38+
39+
@Override
40+
public Deserializer createDeserializer() {
41+
42+
return new Deserializer() {
43+
44+
private final Format m_format;
45+
private final Parser m_parser;
46+
47+
{
48+
try {
49+
m_format = ScifioGateway.getSCIFIO().format().getFormat(".tif");
50+
m_parser = m_format.createParser();
51+
} catch (FormatException e) {
52+
throw new RuntimeException(e);
53+
}
54+
}
55+
56+
@SuppressWarnings({ "rawtypes", "unchecked" })
57+
@Override
58+
public DataCell deserialize(final byte[] bytes, final FileStoreFactory fileStoreFactory)
59+
throws IOException {
60+
61+
final ImgPlusCellFactory factory = new ImgPlusCellFactory(fileStoreFactory);
62+
63+
// TODO this hack should be removed in the future, as soon as
64+
// filename bug is resolved
65+
// We have to set the filename as a NPE would be thrown
66+
// otherwise
67+
final RandomAccessInputStream stream = new RandomAccessInputStream(
68+
ScifioGateway.getSCIFIO().getContext(), bytes) {
69+
@Override
70+
public String getFileName() {
71+
return "";
72+
}
73+
};
74+
75+
try {
76+
77+
final Metadata metadata = m_parser.parse(stream, m_scifioConfig);
78+
metadata.setSource(stream);
79+
80+
final Reader reader = m_format.createReader();
81+
reader.setMetadata(metadata);
82+
reader.setSource(stream, m_scifioConfig);
83+
84+
return factory.createCell((ImgPlus) m_imgOpener.openImgs(reader, m_scifioConfig).get(0));
85+
} catch (final Exception e) {
86+
throw new RuntimeException(e);
87+
}
88+
}
89+
};
90+
}
91+
}
92+
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package org.knime.knip.knimepython2;
2+
3+
import java.io.IOException;
4+
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.List;
7+
8+
import org.knime.knip.base.data.img.ImgPlusValue;
9+
import org.knime.knip.io.ScifioGateway;
10+
import org.knime.knip.knimepython.TypeUtils;
11+
import org.knime.python2.typeextension.Serializer;
12+
import org.knime.python2.typeextension.SerializerFactory;
13+
14+
import io.scif.DefaultImageMetadata;
15+
import io.scif.DefaultMetadata;
16+
import io.scif.FormatException;
17+
import io.scif.ImageMetadata;
18+
import io.scif.Metadata;
19+
import io.scif.Translator;
20+
import io.scif.Writer;
21+
import io.scif.config.SCIFIOConfig;
22+
import io.scif.img.ImgIOException;
23+
import io.scif.img.ImgSaver;
24+
import io.scif.img.SCIFIOImgPlus;
25+
import io.scif.io.ByteArrayHandle;
26+
import io.scif.io.RandomAccessOutputStream;
27+
import net.imagej.ImgPlus;
28+
import net.imagej.axis.Axes;
29+
import net.imagej.axis.CalibratedAxis;
30+
31+
public class ImgPlusSerializerFactory extends SerializerFactory<ImgPlusValue>{
32+
33+
/**
34+
* ImgSaver to write ImgPlus to stream as tif
35+
*/
36+
private ImgSaver m_saver;
37+
38+
/**
39+
* SCIFIO config to read/write images
40+
*/
41+
private SCIFIOConfig m_scifioConfig;
42+
43+
/**
44+
* Constructor
45+
*/
46+
public ImgPlusSerializerFactory() {
47+
super(ImgPlusValue.class);
48+
m_saver = new ImgSaver(ScifioGateway.getSCIFIO().getContext());
49+
m_scifioConfig = new SCIFIOConfig();
50+
m_scifioConfig.groupableSetGroupFiles(false);
51+
m_scifioConfig.imgOpenerSetComputeMinMax(false);
52+
}
53+
54+
@Override
55+
public Serializer<? extends ImgPlusValue<?>> createSerializer() {
56+
57+
return new Serializer<ImgPlusValue<?>>() {
58+
59+
private final Writer m_writer;
60+
61+
{
62+
try {
63+
m_writer = ScifioGateway.format().getWriterByExtension(".tif");
64+
} catch (FormatException e) {
65+
throw new RuntimeException(e);
66+
}
67+
}
68+
69+
@Override
70+
public byte[] serialize(final ImgPlusValue<?> value) throws IOException {
71+
final ImgPlus<?> imgPlus = TypeUtils.converted(value.getImgPlus());
72+
73+
try {
74+
final ByteArrayHandle handle = new ByteArrayHandle();
75+
populateMeta(m_writer, imgPlus, m_scifioConfig, 0);
76+
// HACK Corresponds to filename
77+
m_writer.getMetadata().setDatasetName("");
78+
m_writer.setDest(new RandomAccessOutputStream(handle), 0);
79+
80+
m_saver.saveImg(m_writer, imgPlus.getImg(), m_scifioConfig);
81+
82+
m_writer.close();
83+
84+
return handle.getBytes();
85+
} catch (Exception e) {
86+
e.printStackTrace();
87+
throw new RuntimeException(
88+
"Could not serialize image. Possible reasons: Unsupported image type, dimensionality of the image,...");
89+
}
90+
}
91+
};
92+
}
93+
94+
/**
95+
* This method is copied from SCIFIO
96+
*
97+
* FIXME/TODO: Remove when method available in SCIFIO (see
98+
* https://github.com/scifio/scifio/issues/233)
99+
*
100+
* Uses the provided {@link SCIFIOImgPlus} to populate the minimum metadata
101+
* fields necessary for writing.
102+
*
103+
* @param imageIndex
104+
*/
105+
private void populateMeta(final Writer w, final ImgPlus<?> img, final SCIFIOConfig config, final int imageIndex)
106+
throws FormatException, IOException, ImgIOException {
107+
108+
final Metadata meta = w.getFormat().createMetadata();
109+
110+
// Get format-specific metadata
111+
Metadata imgMeta = ScifioGateway.getSCIFIO().imgUtil().makeSCIFIOImgPlus(img).getMetadata();
112+
113+
final List<ImageMetadata> imageMeta = new ArrayList<ImageMetadata>();
114+
115+
if (imgMeta == null) {
116+
imgMeta = new DefaultMetadata();
117+
imgMeta.createImageMetadata(1);
118+
imageMeta.add(imgMeta.get(0));
119+
} else {
120+
for (int i = 0; i < imgMeta.getImageCount(); i++) {
121+
imageMeta.add(new DefaultImageMetadata());
122+
}
123+
}
124+
125+
// Create Img-specific ImageMetadatas
126+
final int pixelType = ScifioGateway.getSCIFIO().imgUtil().makeType(img.firstElement());
127+
128+
// TODO is there some way to consolidate this with the isCompressible
129+
// method?
130+
final CalibratedAxis[] axes = new CalibratedAxis[img.numDimensions()];
131+
img.axes(axes);
132+
133+
final long[] axisLengths = new long[img.numDimensions()];
134+
img.dimensions(axisLengths);
135+
136+
for (int i = 0; i < imageMeta.size(); i++) {
137+
final ImageMetadata iMeta = imageMeta.get(i);
138+
iMeta.populate(img.getName(), Arrays.asList(axes), axisLengths, pixelType, true, false, false, false, true);
139+
140+
// Adjust for RGB information
141+
if (img.getCompositeChannelCount() > 1) {
142+
if (config.imgSaverGetWriteRGB()) {
143+
iMeta.setPlanarAxisCount(3);
144+
}
145+
iMeta.setAxisType(2, Axes.CHANNEL);
146+
// Split Axes.CHANNEL if necessary
147+
if (iMeta.getAxisLength(Axes.CHANNEL) > img.getCompositeChannelCount()) {
148+
iMeta.addAxis(Axes.get("Channel-planes", false),
149+
iMeta.getAxisLength(Axes.CHANNEL) / img.getCompositeChannelCount());
150+
iMeta.setAxisLength(Axes.CHANNEL, img.getCompositeChannelCount());
151+
}
152+
}
153+
}
154+
155+
// Translate to the output metadata
156+
final Translator t = ScifioGateway.getSCIFIO().translator().findTranslator(imgMeta, meta, false);
157+
158+
t.translate(imgMeta, imageMeta, meta);
159+
160+
w.setMetadata(meta);
161+
}
162+
163+
}

0 commit comments

Comments
 (0)