ImageJ2: How to transfer color table and display range from input to output

I’m struggling to transfer display metadata from an input Dataset/ImageDisplay to a new output built from ImgLib2 Img/RandomAccessibleInterval objects in an ImageJ2 command.

Here’s an example script in Groovy that simply extracts each channel of the input and concatenates them again using Views.stack() (which leads to the Channel axis being last in the axes array):

#@ ImageDisplay im
#@ DisplayService ds

import net.imglib2.view.Views
import net.imagej.axis.Axes
import net.imagej.ImgPlus
import net.imglib2.img.ImgView


d = im.getActiveView().getData()

channelList = []

d.getChannels().times { index ->
	channelList << Views.hyperSlice(d, d.dimensionIndex(Axes.CHANNEL), index)
}
stacked = Views.stack(channelList)
resultImgPlus = new ImgPlus(ImgView.wrap(stacked, d.factory()))

// set all axes except Channel
for (i=0, j=0; i < d.numDimensions(); i++, j++) {
	if (d.axis(i).type() == Axes.CHANNEL) {
		i++
		continue
	}
	resultImgPlus.setAxis(d.axis(i), j)
}

// set Channel axis at last index
resultImgPlus.setAxis(d.axis(Axes.CHANNEL).get(), resultImgPlus.numDimensions() - 1)

// create ImageDisplay
display = ds.createDisplay("result", resultImgPlus)

// get DatasetViews
originalView = im.getActiveView()
resultView = display.getActiveView()

resultView.getChannelCount().times { index ->
	resultView.setChannelRange(index, originalView.getChannelMin(index), originalView.getChannelMax(index))
	resultView.setColorTable(originalView.getColorTables().get(index), index)	
}
resultView.rebuild()

This produces (as expected) a copy of the input image (although with different axis order, internally), but the image displayed in the legacy UI is always shown in red and green (for 2 channels), and intensities are autoscaled to the first slice, instead of transferred from the input display.

image

Also, the above feels far too complicated for the task.
I must be missing something, so I thought I’ll ask the experts here for help. @ctrueden any suggestions?

(I guess I can work around this by using ImageJ1 objects – i.e. ImagePlus etc. – directly. But I’d be interested if there’s a more elegant solution.)

4 Likes