use of net.imglib2.converter.Converters in project bigdataviewer-biop-tools by BIOP.
the class OMETiffExporter method export.
public void export() throws Exception {
if (task != null)
task.setStatusMessage("Exporting " + file.getName() + " with " + nThreads + " threads.");
// Copy metadata from ImagePlus:
IMetadata omeMeta = MetadataTools.createOMEXMLMetadata();
boolean isLittleEndian = false;
boolean isRGB = false;
boolean isInterleaved = false;
int series = 0;
omeMeta.setImageID("Image:" + series, series);
omeMeta.setPixelsID("Pixels:" + series, series);
omeMeta.setImageName(name, series);
omeMeta.setPixelsDimensionOrder(DimensionOrder.XYCZT, series);
if (pixelType instanceof UnsignedShortType) {
omeMeta.setPixelsType(PixelType.UINT16, series);
} else if (pixelType instanceof UnsignedByteType) {
omeMeta.setPixelsType(PixelType.UINT8, series);
} else if (pixelType instanceof FloatType) {
omeMeta.setPixelsType(PixelType.FLOAT, series);
} else if (pixelType instanceof ARGBType) {
isInterleaved = true;
isRGB = true;
omeMeta.setPixelsType(PixelType.UINT8, series);
} else {
throw new UnsupportedOperationException("Unhandled pixel type class: " + pixelType.getClass().getName());
}
omeMeta.setPixelsBigEndian(!isLittleEndian, 0);
// Set resolutions
omeMeta.setPixelsSizeX(new PositiveInteger(width), series);
omeMeta.setPixelsSizeY(new PositiveInteger(height), series);
omeMeta.setPixelsSizeZ(new PositiveInteger(sizeZ), series);
omeMeta.setPixelsSizeT(new PositiveInteger(sizeT), series);
omeMeta.setPixelsSizeC(new PositiveInteger(isRGB ? nChannels * 3 : nChannels), series);
if (isRGB) {
omeMeta.setChannelID("Channel:0", series, 0);
omeMeta.setChannelName("Channel_0", series, 0);
omeMeta.setPixelsInterleaved(isInterleaved, series);
// nSamples = 3; // TODO : check!
omeMeta.setChannelSamplesPerPixel(new PositiveInteger(3), series, 0);
} else {
omeMeta.setChannelSamplesPerPixel(new PositiveInteger(1), series, 0);
omeMeta.setPixelsInterleaved(isInterleaved, series);
for (int c = 0; c < nChannels; c++) {
omeMeta.setChannelID("Channel:0:" + c, series, c);
// omeMeta.setChannelSamplesPerPixel(new PositiveInteger(1), series, c);
int colorCode = converters[c].getColor().get();
// channelLUT.getRed(255);
int colorRed = ARGBType.red(colorCode);
int colorGreen = ARGBType.green(colorCode);
int colorBlue = ARGBType.blue(colorCode);
int colorAlpha = ARGBType.alpha(colorCode);
omeMeta.setChannelColor(new Color(colorRed, colorGreen, colorBlue, colorAlpha), series, c);
omeMeta.setChannelName("Channel_" + c, series, c);
}
}
omeMeta.setPixelsPhysicalSizeX(new Length(voxelSizes[0], unit), series);
omeMeta.setPixelsPhysicalSizeY(new Length(voxelSizes[1], unit), series);
omeMeta.setPixelsPhysicalSizeZ(new Length(voxelSizes[2], unit), series);
// set Origin in XYZ
// TODO : check if enough or other planes need to be set ?
omeMeta.setPlanePositionX(new Length(origin.getDoublePosition(0), unit), 0, 0);
omeMeta.setPlanePositionY(new Length(origin.getDoublePosition(1), unit), 0, 0);
omeMeta.setPlanePositionZ(new Length(origin.getDoublePosition(2), unit), 0, 0);
for (int i = 0; i < nResolutionLevels - 1; i++) {
((IPyramidStore) omeMeta).setResolutionSizeX(new PositiveInteger(mapResToWidth.get(i + 1)), series, i + 1);
((IPyramidStore) omeMeta).setResolutionSizeY(new PositiveInteger(mapResToHeight.get(i + 1)), series, i + 1);
}
// setup writer
PyramidOMETiffWriter writer = new PyramidOMETiffWriter();
// Setting this to false can be problematic!
writer.setWriteSequentially(true);
writer.setMetadataRetrieve(omeMeta);
writer.setBigTiff(true);
writer.setId(file.getAbsolutePath());
writer.setSeries(0);
// TODO : understand why LZW compression does not work!!!
writer.setCompression(compression);
writer.setTileSizeX((int) tileX);
writer.setTileSizeY((int) tileY);
writer.setInterleaved(omeMeta.getPixelsInterleaved(series));
totalTiles = 0;
for (int r = 0; r < nResolutionLevels; r++) {
logger.debug("Saving resolution size " + r);
writer.setResolution(r);
int nXTiles;
int nYTiles;
int maxX, maxY;
if (r != 0) {
maxX = ((IPyramidStore) omeMeta).getResolutionSizeX(0, r).getValue();
maxY = ((IPyramidStore) omeMeta).getResolutionSizeY(0, r).getValue();
} else {
maxX = width;
maxY = height;
}
nXTiles = (int) Math.ceil(maxX / (double) tileX);
nYTiles = (int) Math.ceil(maxY / (double) tileY);
totalTiles += nXTiles * nYTiles;
}
totalTiles *= sizeT * sizeC * sizeZ;
if (task != null)
task.setProgressMaximum(totalTiles);
for (int i = 0; i < nThreads; i++) {
new Thread(() -> {
// loops until no tile needs computation anymore
while (computeNextTile()) {
}
}).start();
}
// generate downsampled resolutions and write to output
for (int r = 0; r < nResolutionLevels; r++) {
logger.debug("Saving resolution size " + r);
writer.setResolution(r);
int nXTiles;
int nYTiles;
int maxX, maxY;
if (r != 0) {
maxX = ((IPyramidStore) omeMeta).getResolutionSizeX(0, r).getValue();
maxY = ((IPyramidStore) omeMeta).getResolutionSizeY(0, r).getValue();
} else {
maxX = width;
maxY = height;
}
nXTiles = (int) Math.ceil(maxX / (double) tileX);
nYTiles = (int) Math.ceil(maxY / (double) tileY);
for (int t = 0; t < sizeT; t++) {
for (int c = 0; c < sizeC; c++) {
for (int z = 0; z < sizeZ; z++) {
for (int y = 0; y < nYTiles; y++) {
for (int x = 0; x < nXTiles; x++) {
long startX = x * tileX;
long startY = y * tileY;
long endX = (x + 1) * (tileX);
long endY = (y + 1) * (tileY);
if (endX > maxX)
endX = maxX;
if (endY > maxY)
endY = maxY;
IntsKey key = new IntsKey(new int[] { r, t, c, z, y, x });
if (nThreads == 0) {
computeTile(key);
} else {
while (!computedBlocks.containsKey(key)) {
synchronized (tileLock) {
tileLock.wait();
}
}
}
int plane = t * sizeZ * sizeC + z * sizeC + c;
IFD ifd = new IFD();
ifd.putIFDValue(IFD.TILE_WIDTH, endX - startX);
ifd.putIFDValue(IFD.TILE_LENGTH, endY - startY);
writer.saveBytes(plane, computedBlocks.get(key), ifd, (int) startX, (int) startY, (int) (endX - startX), (int) (endY - startY));
computedBlocks.remove(key);
tileIterator.decrementQueue();
task.setProgressValue(writtenTiles.incrementAndGet());
}
}
}
}
}
}
writer.close();
computedBlocks.clear();
if (task != null)
task.run(() -> {
});
}
Aggregations