Search code examples
imagematlabtiff

Writing a multipage tif to file in matlab


I'm trying to write a a multipage (1024 pages to be exact) to file.

for frame=1:num_images
    imwrite(output(:,:,frame), 'output.tif', 'tif', 'WriteMode', 'append', 'compression', 'none');
end

I tried this, but writing Int32 to tiff is not supported by imwrite. I've also tried

tiffObj = Tiff('output.tif', 'w');
tiffObj.setTag('ImageLength', x_size);
tiffObj.setTag('ImageWidth', y_size);
tiffObj.setTag('Photometric', Tiff.Photometric.MinIsBlack);
tiffObj.setTag('BitsPerSample', 32);
tiffObj.setTag('SamplesPerPixel', 1);
tiffObj.setTag('RowsPerStrip', 64);
tiffObj.setTag('SampleFormat', Tiff.SampleFormat.Int);
tiffObj.setTag('TileWidth', 128);
tiffObj.setTag('TileLength', 128);
tiffObj.setTag('Compression', Tiff.Compression.None);
tiffObj.setTag('PlanarConfiguration',Tiff.PlanarConfiguration.Chunky);
tiffObj.setTag('Software', 'MATLAB');
tiffObj.write(output);
tiffObj.close();

The tif I imread() has 1 SamplesPerPixel per frame, but when I try to use the same value I get

SamplesPerPixel is 1, but the number of image planes provided was 1204.

If I set it to 1204 Imagej complains

Unsupported SamplesPerPixel: 1204

This is rather frustrating.


Solution

  • The correct way to write multiple pages to a TIFF file is to call Tiff.writeDirectory after each page (2D image) has been written. I agree, the MATLAB documentation is not very clear there, knowing LibTIFF helps in using the Tiff class. For example:

    image = zeros([140,160,16],'uint8'); % this is the image we'll write, should have some actual data in it...
    
    t = Tiff('testing.tif','w');
    tagstruct.ImageLength = size(image,1);
    tagstruct.ImageWidth = size(image,2);
    tagstruct.SampleFormat = 1; % uint
    tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
    tagstruct.BitsPerSample = 8;
    tagstruct.SamplesPerPixel = 1;
    tagstruct.Compression = Tiff.Compression.Deflate;
    tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
    for ii=1:size(image,3)
       setTag(t,tagstruct);
       write(t,image(:,:,ii));
       writeDirectory(t);
    end
    close(t)