diff --git a/src/main/macros/groovy/OverlappedTiledPyramidConversion.groovy b/src/main/macros/groovy/OverlappedTiledPyramidConversion.groovy new file mode 100644 index 00000000..cb638052 --- /dev/null +++ b/src/main/macros/groovy/OverlappedTiledPyramidConversion.groovy @@ -0,0 +1,135 @@ +// imports +import loci.plugins.BF +import loci.plugins.in.ImporterOptions +import loci.formats.ImageReader +import loci.formats.MetadataTools +import loci.formats.FormatTools +import loci.formats.out.PyramidOMETiffWriter +import loci.formats.ome.OMEXMLMetadata +import loci.common.image.IImageScaler +import loci.common.image.SimpleImageScaler +import ome.xml.model.primitives.PositiveInteger +import java.lang.Math +import ij.IJ +import ij.ImagePlus + +// configuration +String file = "/path/to/inputFile.tiff" +String outFile = "/path/to/outputFile.ome.tiff" +int resolutions = 2 +int scale = 2 +int tileSizeX = 1024 +int tileSizeY = 1024 + +// setup reader +ImageReader reader = new ImageReader() +OMEXMLMetadata omeMeta = MetadataTools.createOMEXMLMetadata() +reader.setMetadataStore(omeMeta) +reader.setId(file) + +// add resolution metadata +for (int i = 0; i < resolutions; i++) { + int divScale = Math.pow(scale, i + 1) + omeMeta.setResolutionSizeX(new PositiveInteger((int)(reader.getSizeX() / divScale)), 0, i + 1) + omeMeta.setResolutionSizeY(new PositiveInteger((int)(reader.getSizeY() / divScale)), 0, i + 1) +} + +// setup writer with tiling +PyramidOMETiffWriter writer = new PyramidOMETiffWriter() +writer.setMetadataRetrieve(omeMeta) +tileSizeX = writer.setTileSizeX(tileSizeX) +tileSizeY = writer.setTileSizeY(tileSizeY) +writer.setId(outFile) +int type = reader.getPixelType() + +// create image scaler for downsampling +SimpleImageScaler scaler = new SimpleImageScaler() + +// convert to Pyramidal OME-TIFF using tiling +for (series = 0; series < reader.getSeriesCount(); series++) { + reader.setSeries(series) + writer.setSeries(series) + + // convert each image in the current series + for (image = 0; image < reader.getImageCount(); image++) { + int width = reader.getSizeX() + int height = reader.getSizeY() + + // Determined the number of tiles to read and write + int nXTiles = width / tileSizeX + int nYTiles = height / tileSizeY + if (nXTiles * tileSizeX != width) { + nXTiles = nXTiles + 1 + } + if (nYTiles * tileSizeY != height) { + nYTiles = nYTiles + 1 + } + + // Convert the main image + for (int y = 0; y < nYTiles; y++) { + for (int x = 0; x < nXTiles; x++) { + writer.setResolution(0) + // The x and y coordinates for the current tile + tileX = x * tileSizeX + tileY = y * tileSizeY + int effTileSizeX = tileSizeX + if ((tileX + tileSizeX) >= width) { + effTileSizeX = width - tileX; + } + int effTileSizeY = tileSizeY + if ((tileY + tileSizeY) >= height) { + effTileSizeY = height - tileY + } + // Read tiles from the input file and write them to the output OME-Tiff + byte[] buf = reader.openBytes(image, tileX, tileY, effTileSizeX, effTileSizeY) + writer.saveBytes(image, buf, tileX, tileY, effTileSizeX, effTileSizeY) + } + } + + // Create the downsampled resolutions and write to output + for (int i = 0; i < resolutions; i++) { + int currentScale = Math.pow(scale, i + 1) + writer.setResolution(i + 1) + int resolutionWidth = width / currentScale + int resolutionHeight = height / currentScale + nXTiles = resolutionWidth / tileSizeX + nYTiles = resolutionHeight / tileSizeY + if ((nXTiles * tileSizeX) != resolutionWidth) { + nXTiles = nXTiles + 1 + } + if ((nYTiles * tileSizeY) != resolutionHeight) { + nYTiles = nYTiles + 1 + } + for (int y = 0; y < nYTiles; y++) { + for (int x = 0; x < nXTiles; x++) { + tileX = x * tileSizeX + tileY = y * tileSizeY + effTileSizeX = tileSizeX * currentScale + if (((tileX * currentScale) + effTileSizeX) >= width) { + effTileSizeX = width - (tileX * currentScale) + } + effTileSizeY = tileSizeY * currentScale + if (((tileY * currentScale) + effTileSizeY) >= height) { + effTileSizeY = height - (tileY * currentScale) + } + byte[] tile = reader.openBytes(image, tileX * currentScale, tileY * currentScale, effTileSizeX, effTileSizeY) + byte[] downsample = scaler.downsample(tile, effTileSizeX, effTileSizeY, currentScale, FormatTools.getBytesPerPixel(type), reader.isLittleEndian(), + FormatTools.isFloatingPoint(type), reader.getRGBChannelCount(), reader.isInterleaved()) + writer.saveBytes(image, downsample, tileX, tileY, (int)(effTileSizeX / currentScale), (int)(effTileSizeY / currentScale)) + } + } + } + } +} + +writer.close() +reader.close() + +IJ.log("Done") + +ImporterOptions options = new ImporterOptions() +options.setColorMode(ImporterOptions.COLOR_MODE_COMPOSITE) +options.setId(outFile) +options.setSeriesOn(2, true) +ImagePlus[] imps = BF.openImagePlus(options) +imps[0].show() \ No newline at end of file diff --git a/src/main/macros/jython/OverlappedTiledPyramidConversion.py b/src/main/macros/jython/OverlappedTiledPyramidConversion.py new file mode 100644 index 00000000..d0bbea50 --- /dev/null +++ b/src/main/macros/jython/OverlappedTiledPyramidConversion.py @@ -0,0 +1,128 @@ +# imports +from loci.plugins import BF +from loci.plugins.in import ImporterOptions +from loci.formats import ImageReader +from loci.formats import MetadataTools +from loci.formats import FormatTools +from loci.formats.out import PyramidOMETiffWriter +from loci.common.image import IImageScaler +from loci.common.image import SimpleImageScaler +from ome.xml.model.primitives import PositiveInteger +from java.lang import Math +from ij import IJ +import math + +# configuration +file = "/path/to/inputFile.tiff" +outFile = "/path/to/outputFile.ome.tiff" + +# the number of resolutions in the output file +resolutions = 2 + +# the scale to be used for the downsampling +scale = 2 + +# set the tile sizes to be used +tileSizeX = 1024 +tileSizeY = 1024 + +# setup reader +reader = ImageReader() +omeMeta = MetadataTools.createOMEXMLMetadata() +reader.setMetadataStore(omeMeta) +reader.setId(file) + +# add resolution metadata +for i in range(resolutions): + divScale = Math.pow(scale, i + 1) + omeMeta.setResolutionSizeX(PositiveInteger(int(reader.getSizeX() / divScale)), 0, i + 1) + omeMeta.setResolutionSizeY(PositiveInteger(int(reader.getSizeY() / divScale)), 0, i + 1) + +# setup writer with tiling +writer = PyramidOMETiffWriter() +writer.setMetadataRetrieve(omeMeta) +tileSizeX = writer.setTileSizeX(tileSizeX) +tileSizeY = writer.setTileSizeY(tileSizeY) +writer.setId(outFile) +type = reader.getPixelType() + +# create image scaler for downsampling +scaler = SimpleImageScaler() + +# convert to Pyramidal OME-TIFF using tiling +for series in range(reader.getSeriesCount()): + reader.setSeries(series) + writer.setSeries(series) + + # convert each image in the current series + for image in range(reader.getImageCount()): + width = reader.getSizeX() + height = reader.getSizeY() + + # Determined the number of tiles to read and write + nXTiles = int(math.floor(width / tileSizeX)) + nYTiles = int(math.floor(height / tileSizeY)) + if nXTiles * tileSizeX != width: + nXTiles = nXTiles + 1 + if nYTiles * tileSizeY != height: + nYTiles = nYTiles + 1; + + # Convert the main image + for y in range(nYTiles): + for x in range(nXTiles): + writer.setResolution(0); + # The x and y coordinates for the current tile + tileX = x * tileSizeX; + tileY = y * tileSizeY; + effTileSizeX = tileSizeX + if (tileX + tileSizeX) >= width: + effTileSizeX = width - tileX + effTileSizeY = tileSizeY + if (tileY + tileSizeY) >= height: + effTileSizeY = height - tileY + # Read tiles from the input file and write them to the output OME-Tiff + buf = reader.openBytes(image, tileX, tileY, effTileSizeX, effTileSizeY) + writer.saveBytes(image, buf, tileX, tileY, effTileSizeX, effTileSizeY) + + # Create the downsampled resolutions and write to output + for i in range(resolutions): + currentScale = int(Math.pow(scale, i + 1)) + writer.setResolution(i + 1) + resolutionWidth = width / currentScale + resolutionHeight = height / currentScale + nXTiles = int(math.floor(resolutionWidth / tileSizeX)) + nYTiles = int(math.floor(resolutionHeight / tileSizeY)) + if nXTiles * tileSizeX != resolutionWidth: + nXTiles = nXTiles + 1 + if nYTiles * tileSizeY != resolutionHeight: + nYTiles = nYTiles + 1 + for y in range(nYTiles): + for x in range(nXTiles): + # Calculate the correct size and offset for each tile + tileX = x * tileSizeX + tileY = y * tileSizeY + effTileSizeX = tileSizeX * currentScale + if ((tileX * currentScale) + effTileSizeX) >= width: + effTileSizeX = width - (tileX * currentScale) + effTileSizeY = tileSizeY * currentScale + if ((tileY * currentScale) + effTileSizeY) >= height: + effTileSizeY = height - (tileY * currentScale) + + # Read the tile, create the downsampled version and then write to output + tile = reader.openBytes(image, tileX * currentScale, tileY * currentScale, effTileSizeX, effTileSizeY) + downsample = scaler.downsample(tile, effTileSizeX, effTileSizeY, currentScale, FormatTools.getBytesPerPixel(type), reader.isLittleEndian(), + FormatTools.isFloatingPoint(type), reader.getRGBChannelCount(), reader.isInterleaved()) + writer.saveBytes(image, downsample, tileX, tileY, effTileSizeX / currentScale, effTileSizeY / currentScale) + +writer.close(); +reader.close(); + +IJ.log("Done") + +options = ImporterOptions() +options.setColorMode(ImporterOptions.COLOR_MODE_COMPOSITE) +options.setId(outFile) +options.setSeriesOn(2, True); +imps = BF.openImagePlus(options) +for imp in imps: + imp.show() \ No newline at end of file diff --git a/src/main/macros/jython/PyramidConversion.py b/src/main/macros/jython/PyramidConversion.py new file mode 100644 index 00000000..b5e8e8dc --- /dev/null +++ b/src/main/macros/jython/PyramidConversion.py @@ -0,0 +1,58 @@ +# imports +from loci.plugins import BF +from loci.plugins.in import ImporterOptions +from loci.formats import ImageReader +from loci.formats import MetadataTools +from loci.formats import FormatTools +from loci.formats.out import OMETiffWriter +from loci.common.image import IImageScaler +from loci.common.image import SimpleImageScaler +from ome.xml.model.primitives import PositiveInteger +from ome.units import UNITS +from java.lang import Math +from ij import IJ + +# settings +file = "/path/to/inputFile.tiff" +outFile = "/path/to/outputFile.ome.tiff" +resolutions = 4 +scale = 2 + +# setup reader and parse metadata +reader = ImageReader() +omeMeta = MetadataTools.createOMEXMLMetadata() +reader.setMetadataStore(omeMeta) +reader.setId(file) + +# setup resolutions +for i in range(resolutions): + divScale = Math.pow(scale, i + 1) + omeMeta.setResolutionSizeX(PositiveInteger(int(reader.getSizeX() / divScale)), 0, i + 1) + omeMeta.setResolutionSizeY(PositiveInteger(int(reader.getSizeY() / divScale)), 0, i + 1) + +# setup writer +writer = OMETiffWriter() +writer.setMetadataRetrieve(omeMeta) +writer.setId(outFile) +type = reader.getPixelType() + +# read and write main image +img = reader.openBytes(0) +writer.saveBytes(0, img) + +# create ImageScaler for downsampling +scaler = SimpleImageScaler() + +# generate downsampled resolutions and write to output +for i in range(resolutions): + writer.setResolution(i + 1) + x = omeMeta.getResolutionSizeX(0, i + 1).getValue() + y = omeMeta.getResolutionSizeY(0, i + 1).getValue() + downsample = scaler.downsample(img, reader.getSizeX(), reader.getSizeY(), Math.pow(scale, i + 1), + FormatTools.getBytesPerPixel(type), reader.isLittleEndian(), + FormatTools.isFloatingPoint(type), reader.getRGBChannelCount(), + reader.isInterleaved()) + writer.saveBytes(0, downsample) + +writer.close() +reader.close() \ No newline at end of file diff --git a/src/main/macros/jython/TiledConversion.py b/src/main/macros/jython/TiledConversion.py new file mode 100644 index 00000000..c4707934 --- /dev/null +++ b/src/main/macros/jython/TiledConversion.py @@ -0,0 +1,65 @@ +# imports +from loci.plugins import BF +from loci.formats import ImageReader +from loci.formats import MetadataTools +from loci.formats import FormatTools +from loci.formats.out import OMETiffWriter +from loci.common.image import IImageScaler +from loci.common.image import SimpleImageScaler +from ome.xml.model.primitives import PositiveInteger +from java.lang import Math +from ij import IJ +import math + +# configuation +file = "/path/to/inputFile.tiff" +outFile = "/path/to/outputFile.ome.tiff" +resolutions = 3; +scale = 2; +tileSizeX = 512 +tileSizeY = 512 + +# setup image reader and writer +reader = ImageReader() +omeMeta = MetadataTools.createOMEXMLMetadata() +reader.setMetadataStore(omeMeta) +reader.setId(file) + +writer = OMETiffWriter(); +writer.setMetadataRetrieve(omeMeta) +writer.setInterleaved(reader.isInterleaved()) +writer.setTileSizeX(tileSizeX) +writer.setTileSizeY(tileSizeY) +writer.setId(outFile) + +# convert to OME-TIFF using tiled reading and writing +for series in range(reader.getSeriesCount()): + reader.setSeries(series) + writer.setSeries(series) + + # convert each image in the current series + for image in range(reader.getImageCount()): + width = reader.getSizeX() + height = reader.getSizeY() + + # Determined the number of tiles to read and write + nXTiles = int(math.floor(width / tileSizeX)) + nYTiles = int(math.floor(height / tileSizeY)) + if nXTiles * tileSizeX != width: + nXTiles = nXTiles + 1 + if nYTiles * tileSizeY != height: + nYTiles = nYTiles + 1 + for y in range(nYTiles): + for x in range(nXTiles): + # The x and y coordinates for the current tile + tileX = x * tileSizeX + tileY = y * tileSizeY + # Read tiles from the input file and write them to the output OME-Tiff + buf = reader.openBytes(image, tileX, tileY, tileSizeX, tileSizeY) + writer.saveBytes(image, buf, tileX, tileY, tileSizeX, tileSizeY) + + +# close reader and writer +writer.close() +reader.close() +IJ.log("Done") \ No newline at end of file