Writing tiff file with multi channel and slices

35 views (last 30 days)
Hello,
I would like to make a tiff file with c=2, z=10, t=1. Input array is 4 dimension, [height, width, channel, slice]. Currently I am using the code below, however, the output tiff file becomes c=1, z=20, t=1. Can anybody help me to fix it?
function write3Dtiff_Slice(array, filename)
dims = size(array);
% Ensure the array has four dimensions
if length(dims) < 4
dims(end+1:4) = 1;
end
% Set data type specific fields
if isa(array, 'single')
bitsPerSample = 32;
sampleFormat = Tiff.SampleFormat.IEEEFP;
elseif isa(array, 'uint16')
bitsPerSample = 16;
sampleFormat = Tiff.SampleFormat.UInt;
elseif isa(array, 'uint8')
bitsPerSample = 8;
sampleFormat = Tiff.SampleFormat.UInt;
else
disp('Unsupported data type');
return;
end
% Loop through slices
for s = 1:dims(4)
% Open TIFF file for each slice in append mode
outtiff = Tiff(filename, 'a');
% Loop through channels for the current slice
for c = 1:dims(3)
% Set tag structure for each channel of each slice
tagstruct.ImageLength = dims(1);
tagstruct.ImageWidth = dims(2);
tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tagstruct.SamplesPerPixel = 1;
tagstruct.BitsPerSample = bitsPerSample;
tagstruct.SampleFormat = sampleFormat;
% Set the tag for the current channel
outtiff.setTag(tagstruct);
% Write the channel data
outtiff.write(array(:,:,c,s));
% Create a new directory for the next channel unless it's the last channel of the last slice
if c ~= dims(3) || s ~= dims(4)
outtiff.writeDirectory();
end
end
% Close the file for the current slice
outtiff.close();
end
end

Accepted Answer

DGM
DGM on 16 Dec 2023
Edited: DGM on 16 Dec 2023
It's doing exactly what you're telling it to do. You have a stack of size [H W C F]. You're splitting the stack into C*F individual single-channel images. If that's not what you want, then what do you want?
This writes a set of 2-channel frames instead of a bunch of loose channels.
fname = 'fname.tif';
% a MxNx2x5 4D image
inpict = imread('peppers.png');
inpict = repmat(inpict(:,:,1:2),[1 1 1 5]);
% create the file
write3Dtiff_Slice(inpict,fname)
% get the information in the multitiff image
info = imfinfo(fname);
nframes = numel(info);
% read images to check that it's the expected size
% this assumes all the frames are the same class and size
C(:,:,:,1) = imread(fname,1);
C = repmat(C,[1 1 1 nframes]);
for f = 2:nframes
C(:,:,:,f) = imread(fname,f);
end
% test it
size(C) % the size is as expected
ans = 1×4
384 512 2 5
isequal(C,inpict) % it's the same as the original
ans = logical
1
function write3Dtiff_Slice(array, filename)
dims = size(array);
% Ensure the array has four dimensions
if length(dims) < 4
dims(end+1:4) = 1;
end
% Set data type specific fields
if isa(array, 'single')
bitsPerSample = 32;
sampleFormat = Tiff.SampleFormat.IEEEFP;
elseif isa(array, 'uint16')
bitsPerSample = 16;
sampleFormat = Tiff.SampleFormat.UInt;
elseif isa(array, 'uint8')
bitsPerSample = 8;
sampleFormat = Tiff.SampleFormat.UInt;
else
disp('Unsupported data type');
return;
end
% Open TIFF file for each slice in append mode
outtiff = Tiff(filename, 'a');
% Loop through slices
for s = 1:dims(4)
% Set tag structure for each frame
tagstruct.ImageLength = dims(1);
tagstruct.ImageWidth = dims(2);
tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
tagstruct.ExtraSamples = Tiff.ExtraSamples.AssociatedAlpha;
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tagstruct.SamplesPerPixel = 2;
tagstruct.BitsPerSample = bitsPerSample;
tagstruct.SampleFormat = sampleFormat;
% Set the tag for the current frame
outtiff.setTag(tagstruct);
% Write the frame
outtiff.write(array(:,:,:,s));
% Create a new directory for the next frame
if s ~= dims(4)
outtiff.writeDirectory();
end
end
% Close the file
outtiff.close();
end
Note that you're always opening the file in 'append' mode, so if you write to an existing file, you'll always add more frames to it.

More Answers (1)

Image Analyst
Image Analyst on 16 Dec 2023
Edited: Image Analyst on 16 Dec 2023
What is z and t?
If you want the loop to only go from c=1 to c=2, instead of this:
for c = 1:dims(3)
have this:
for c = 1 : 2
Then I think it will write only the red channel and the blue channel.

Categories

Find more on File Operations in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!