Having difficulty getting new series created

I’m trying to write multiple images into a single file. Each image as a separate series.
Below, is the chunk of code that I use for the writer for a case with two images.
ServiceFactory factory = new ServiceFactory();
OMEXMLService service = factory.getInstance(OMEXMLService.class);
IMetadata meta = service.createOMEXMLMetadata();
meta.createRoot();
for (int i=0; i<2; i++) {
meta.setImageID(“Image:”+i,i);
meta.setPixelsID(“Pixels:”+i,i);
meta.setChannelID(“Channel:”+i+":0", i, 0);
meta.setChannelSamplesPerPixel(new PositiveInteger(3),i, 0);
meta.setPixelsBigEndian(Boolean.TRUE, i);
meta.setPixelsInterleaved(Boolean.TRUE, i);
meta.setPixelsDimensionOrder(DimensionOrder.XYCZT, i);
meta.setPixelsType(PixelType.UINT8, i);
meta.setPixelsSizeX(new PositiveInteger(SizeX),i);
meta.setPixelsSizeY(new PositiveInteger(SizeY),i);
meta.setPixelsSizeZ(new PositiveInteger(1), i);
meta.setPixelsSizeC(new PositiveInteger(3), i);
meta.setPixelsSizeT(new PositiveInteger(1), i);
meta.setPixelsPhysicalSizeX(new Length(0.3470547596724842, UNITS.MICROMETER), i);
meta.setPixelsPhysicalSizeY(new Length(0.3470491808827766, UNITS.MICROMETER), i);
meta.setPixelsPhysicalSizeZ(new Length(1, UNITS.MICROMETER), i);
}
writer.setMetadataRetrieve((MetadataRetrieve) meta);

The following meta data is created:

<?xml version="1.0" encoding="UTF-8"?>

When I open the file, I can see the two mages fine in GIMP, but when I display with showinf, I see the following with both images in the same series:

Checking file format [Tagged Image File Format]
Initializing reader
TiffDelegateReader initializing old2.tif
Reading IFDs
Populating metadata
Checking comment style
Populating OME metadata
Initialization took 0.079s

Reading core metadata
filename = old2.tif
Series count = 1
Series #0 :
Image count = 2
RGB = true (3)
Interleaved = false
Indexed = false (false color)
Width = 49512
Height = 38578
SizeZ = 1
SizeT = 2
SizeC = 3 (effectively 1)
Tile size = 512 x 512
Thumbnail size = 128 x 99
Endianness = motorola (big)
Dimension order = XYCZT (uncertain)
Pixel type = uint8
Valid bits per pixel = 8
Metadata complete = true
Thumbnail series = false
-----
Plane #0 <=> Z 0, C 0, T 0
Plane #1 <=> Z 0, C 0, T 1

Reading global metadata
BitsPerSample: 8
Compression: LZW
ImageLength: 38578
ImageWidth: 49512
MetaDataPhotometricInterpretation: RGB
MetaMorph: no
NumberOfChannels: 3
PhotometricInterpretation: RGB
PlanarConfiguration: Chunky
ResolutionUnit: Centimeter
SampleFormat: unsigned integer
SamplesPerPixel: 3
Software: OME Bio-Formats 6.3.1
TileLength: 512
TileWidth: 512
XResolution: 28813.896
YResolution: 28814.359
hyperstack: true

How can I get each image in it’s own series? Thanks, Erich

Hi @Erich_Bremer, are you calling setSeries before saving the pixel bytes?
writer.setSeries(writerSeries);

Yes, just before the writer.saveBytes(0, buf, tileX, tileY, effTileSizeX, effTileSizeY);. I’m using bioformats 6.3.1

The code listed should be ok, can you run the below sample code to confirm that it is working for you ok?

  String id = "my/output/file.ome.tiff;
  int w = 512, h = 512, c = 3;
  int pixelType = FormatTools.UINT8;
  byte[] img = new byte[w * h * c * FormatTools.getBytesPerPixel(pixelType)];
  for (int i=0; i<img.length; i++) img[i] = (byte) (256 * Math.random());
  ServiceFactory factory = new ServiceFactory();
  OMEXMLService service = factory.getInstance(OMEXMLService.class);
  IMetadata meta = service.createOMEXMLMetadata();
  for (int i=0; i<2; i++) {
    meta.setImageID("Image:"+i,i);
    meta.setPixelsID("Pixels:"+i,i);
    meta.setChannelID("Channel:"+i+":0", i, 0);
    meta.setChannelSamplesPerPixel(new PositiveInteger(3),i, 0);
    meta.setPixelsBigEndian(Boolean.TRUE, i);
    meta.setPixelsInterleaved(Boolean.TRUE, i);
    meta.setPixelsDimensionOrder(DimensionOrder.XYCZT, i);
    meta.setPixelsType(PixelType.UINT8, i);
    meta.setPixelsSizeX(new PositiveInteger(w),i);
    meta.setPixelsSizeY(new PositiveInteger(h),i);
    meta.setPixelsSizeZ(new PositiveInteger(1), i);
    meta.setPixelsSizeC(new PositiveInteger(3), i);
    meta.setPixelsSizeT(new PositiveInteger(1), i);
    meta.setPixelsPhysicalSizeX(new Length(0.3470547596724842, UNITS.MICROMETER), i);
    meta.setPixelsPhysicalSizeY(new Length(0.3470491808827766, UNITS.MICROMETER), i);
    meta.setPixelsPhysicalSizeZ(new Length(1, UNITS.MICROMETER), i);
    }
  IFormatWriter writer = new ImageWriter();
  writer.setMetadataRetrieve(meta);
  writer.setId(id);
  writer.setSeries(0);
  writer.saveBytes(0, img);
  writer.setSeries(1);
  writer.saveBytes(0, img);
  writer.close();

No, same thing. “work.tif” is the outputfile of your sample code.

D:\vsi>showinf -nopix work.tif
*** One or more readers is misbehaving. See the debug output for more information. e.g.:
loci.formats.in.APLReader@67b9b51a -> java.lang.NullPointerException(‘null’) ***
Checking file format [Tagged Image File Format]
Initializing reader
TiffDelegateReader initializing work.tif
Reading IFDs
Populating metadata
Checking comment style
Populating OME metadata
Initialization took 0.065s

Reading core metadata
filename = work.tif
Series count = 1
Series #0 :
Image count = 2
RGB = true (3)
Interleaved = false
Indexed = false (false color)
Width = 512
Height = 512
SizeZ = 1
SizeT = 2
SizeC = 3 (effectively 1)
Tile size = 512 x 512
Thumbnail size = 128 x 128
Endianness = motorola (big)
Dimension order = XYCZT (uncertain)
Pixel type = uint8
Valid bits per pixel = 8
Metadata complete = true
Thumbnail series = false
-----
Plane #0 <=> Z 0, C 0, T 0
Plane #1 <=> Z 0, C 0, T 1

Reading global metadata
BitsPerSample: 8
Compression: Uncompressed
ImageLength: 512
ImageWidth: 512
MetaDataPhotometricInterpretation: RGB
MetaMorph: no
NumberOfChannels: 3
PhotometricInterpretation: RGB
PlanarConfiguration: Planar
ResolutionUnit: Centimeter
SampleFormat: unsigned integer
SamplesPerPixel: 3
Software: OME Bio-Formats 6.3.1
XResolution: 28813.896
YResolution: 28814.359
hyperstack: true

Reading metadata

Ok, I’ve only just noticed you are using standard TIFF. This should really be better documented somewhere as the output here is certainly going to be confusing for people. For standard TIFF files there is no tag on the IFD to really represent which series a plane is a part of. As such Bio-Formats cant determined different series in the same way but instead allows for splitting of series if the planes contain either a different dimension or a different pixel type.

If you are able to swap the output to OME-TIFF then that should get you what you want as the series information is based on the OME-XML header.

It works now that I switched it to OMETiffWriter. However, explicitly specifying TiffWriter was me playing around to see what would work and not work. It also did not work when I used your original

IFormatWriter writer = new ImageWriter();
instead of the now working
OMETiffWriter writer = new OMETiffWriter();

does ImageWriter favor TiffWriter instead of OMETiffWriter?

In that case ImageWriter will base it on the file extension used and is configured using https://github.com/ome/bioformats/blob/develop/components/formats-api/src/loci/formats/writers.txt

So .ome.tiff or ome.tif will use OMETiffWriter, just .tiff or .tiff will use TiffWriter