Closed frauzufall closed 4 years ago
@frauzufall Shall we go through this on Monday?
@frauzufall After playing around a bit, I believe we do not need DatasetView
here after all. Below is working code. The only question is whether to put it directly into DefaultImageDisplay
, or make a Converter
plugin that the image display logic uses internally.
ImageJ ij = new ImageJ();
ij.ui().showUI();
// A nice ARGB image.
Img<ARGBType> argbImage = ArrayImgs.argbs(512, 384);
Cursor<ARGBType> c = argbImage.cursor();
for (int y = 0; y < argbImage.dimension(1); y++) {
for (int x = 0; x < argbImage.dimension(0); x++) {
int r = (x + y) % 255;
int g = (x * y) % 255;
int b = (y - x) % 255;
int a = 255;
c.next().set(ARGBType.rgba(r, g, b, a));
}
}
// The ARGB image is not showable:
//ij.ui().show(argbImage);
ImageJFunctions.show(argbImage);
// Internal conversions needed to convert to Dataset.
// This could (should?) be a SciJava Converter plugin.
List<RandomAccessibleInterval<UnsignedByteType>> channels = Arrays.asList(
Converters.argbChannel(argbImage, 1),
Converters.argbChannel(argbImage, 2),
Converters.argbChannel(argbImage, 3)
// Converters.argbChannel(argbImage, 0)
);
Dataset dataset = ij.dataset().create(Views.stack(channels));
dataset.setAxis(new IdentityAxis(Axes.CHANNEL), dataset.numDimensions() - 1);
// NB: The following call gives a hint to the ImageJ Legacy layer that
// this dataset should be collapsed to IJ1's RGB type. The dataset must
// be uint8 with the third dimension axis of type Channel and length 3,
// or else an exception will be thrown.
dataset.setRGBMerged(true);
ij.ui().show(dataset);
The methods DefaultDatasetService.create(...)
are responsible for the conversion of RAI to Dataset
. But the code lags support for ARGBType, and that's why we get the Exception. I think DefaultDatasetService
is the place the fix the problem. And yes, the code for the legacy image display looks at the RGBMerged flag to decide whether to display the image colorful or multichannel.
This Fix changes DatasetService.create(RandomAccessibleInterval<T> image)
and DatasetService.create(ImgPlus<T> image)
to support ARGBType. The methods now use the code that @ctrueden posted above to automatically split the ARGBType into channels before converting it to Dataset
.
The following code can now be used to correctly convert an Img<ARGBType>
to Dataset
:
// Some RGB image
Img<ARGBType> image = ArrayImgs.argbs(10, 10);
// Convert it to dataset (this internally splits the RGB image into three channels)
Dataset dataset = datasetService.create(image);
This fix also enables UIService
(and DefaultImageDisplay
) to show the ARGBType image correctly.
Thank you, @maarzt !
@ctrueden Thank you for the quick review & merge! :heart_eyes:
ARGBType
images into a stack of their color channelsRGBA
, so I moved the alpha channel to the last indexWe discussed this here in the forum (ping @hanslovsky @ctrueden). I would prefer a solution though where I actually see the colors... How would I do that?