View License

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video

Highlights from
Save and load a multiframe TIFF image

4.81818
4.8 | 11 ratings Rate this file 55 Downloads (last 30 days) File Size: 7.15 KB File ID: #35684 Version: 4.3
image thumbnail

Save and load a multiframe TIFF image

by

YoonOh Tak (view profile)

 

16 Mar 2012 (Updated )

Much faster than 'imwrite' and supports complex number images.

| Watch this File

File Information
Description

clearvars;
[~,~,Z] = peaks(100);
Z = single(Z);
Z_index = uint8((Z - min(Z(:))) * (255 / (max(Z(:)) - min(Z(:)))));
Z_color = uint8(ind2rgb(Z_index, hsv(256)*256));
Z_alpha = Z_color; Z_alpha(:,:,4) = repmat(0:1/100:1-1/100, 100, 1)*255;
Z_color_multiframe = reshape([Z_color(:)*0.2 Z_color(:)*0.6 Z_color(:)], 100, 100, 3, 3);
% 8-bit, grayscale image
clear options;
saveastiff(uint8(Z_index), 'Z_uint8.tif');
% Lossless LZW compression
clear options;
options.comp = 'adobe';
saveastiff(uint8(Z_index), 'Z_uint8_compress.tif', options);
% Overwrite to an existing file
clear options;
options.overwrite = true;
options.compress = 'adobe';
saveastiff(uint8(Z_index), 'Z_uint8_compress.tif', options);
% Allow message printing.
clear options;
options.message = true;
saveastiff(uint8(Z_index), 'Z_uint8_Message.tif', options);
% 16 bit, grayscale image
clear options;
saveastiff(uint16(single(Z_index)/255*(2^16-1)), 'Z_uint16.tif');
% 32 bit, grayscale image
clear options;
saveastiff(uint32(single(Z_index)/255*(2^32-1)), 'Z_uint32.tif');
% 32 bit single, grayscale image
clear options;
saveastiff(Z, 'Z_single.tif');
% Color image
clear options;
options.color = true;
saveastiff(Z_color, 'Z_rgb.tif', options);

% Color image with alpha channel
clear options;
options.color = true;
saveastiff(Z_alpha, 'Z_alpha.tif', options);

% Save each R, G and B chanels of the color image, separately.
clear options;
saveastiff(Z_color, 'Z_rgb_channel.tif');

% Save the multi-frame RGB color image
clear options;
options.color = true;
saveastiff(Z_color_multiframe, 'Z_rgb_multiframe.tif', options);

% 32 bit single, 50x50x50 volume data
clear options;
saveastiff(single(rand(50, 50, 50)), 'volume_50x50x50.tif');

% Append option is ignored if path dose not exist.
clear options;
options.append = true;
saveastiff(Z_index, 'Z_uint8_append.tif', options);

% You can append any type of image to an existing tiff file.
clear options;
options.append = true;
saveastiff(single(rand(10, 10, 3)), 'Z_uint8_append.tif', options);
options.color = true;
saveastiff(Z_color_multiframe, 'Z_uint8_append.tif', options);

% Save image to a sub directory
clear options;
saveastiff(uint8(Z_index), 'sub1/sub2/Z_uint8.tif');
options.append = true;
saveastiff(uint8(Z_index), 'sub1/sub2/Z_uint8.tif', options);

% Save complex number images
saveastiff(fft2(Z_index), 'Z_fft2_gray.tif');
saveastiff(fft2(Z_color), 'Z_fft2_color.tif', options);
clear options;
options.color = true;
options.append = true;
saveastiff(fft2(Z_index), 'Z_fft2_append.tif');
saveastiff(fft2(Z_color), 'Z_fft2_append.tif', options);
saveastiff(fft2(Z_color), 'Z_fft2_append.tif', options);
saveastiff(fft2(Z_alpha), 'Z_fft2_append.tif', options);

% Load multiframe tiff
multiframe = loadtiff('volume_50x50x50.tif');
complexframe = loadtiff('Z_uint8_append.tif');
subdir = loadtiff('sub1/sub2/Z_uint8.tif');
fftgray = loadtiff('Z_fft2_gray.tif');
fftcolor = loadtiff('Z_fft2_color.tif');
fftappend = loadtiff('Z_fft2_append.tif');

% Big Tiff File (64 bit)
[~,maxArraySize]=computer;
is64bitMatlab = maxArraySize> 2^31;
if is64bitMatlab
    % Use 'big' option to save larget than 4GB files .
    clear options;
    options.big = true; % Use BigTIFF format
    saveastiff(single(zeros(24000, 24000)), 'BigTiff(2GB+2GB).btf', options);
    options.append = true;
    saveastiff(single(zeros(24000, 24000)), 'BigTiff(2GB+2GB).btf', options); % 4GB Big TIFF file
    bigtiff = loadtiff('BigTiff(2GB+2GB).btf');
end

Required Products MATLAB
MATLAB release MATLAB 7.10 (R2010a)
MATLAB Search Path
/
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (30)
24 Oct 2016 Yishai

Yishai (view profile)

Thanks YoonOh, I think I found the issue with my previous post.

Well done, again!

Comment only
20 Oct 2016 YoonOh Tak

YoonOh Tak (view profile)

This is my code to test your problem, Yishai.
--------------------------------------------
clearvars;
p=1000; s=7;

jpgBig1=uint8(rand(256,256,p,'single').*255);
jpgBig1=repmat(jpgBig1,[1,1,s]);

opt.big=true;
opt.compress = 'jpeg';
saveastiff(jpgBig1,'jpgBig.tif',opt);
jpgBig2=loadtiff('jpgBig.tif');

opt.message=true;
for i=1:s
saveastiff(jpgBig1(:,:,p*(i-1)+1:p*i),['jpgSmall' num2str(i,'%02d') '.tif'],opt);
end
--------------------------------------------

And I got this resutls.
--------------------------------------------
The file was saved successfully. Elapsed time : 160.731 s.
The file was loaded successfully. Elapsed time : 14.068 s.
The file was saved successfully. Elapsed time : 8.866 s.
The file was saved successfully. Elapsed time : 10.245 s.
The file was saved successfully. Elapsed time : 8.916 s.
The file was saved successfully. Elapsed time : 8.915 s.
The file was saved successfully. Elapsed time : 9.031 s.
The file was saved successfully. Elapsed time : 9.357 s.
The file was saved successfully. Elapsed time : 9.119 s.
--------------------------------------------
Could you modify this code to reproduce your problem?

Comment only
15 Oct 2016 Yishai

Yishai (view profile)

Hi YoonOh,

This is a very useful piece of software, a good wrapper for the opaque and unfriendly Tiff class that matlab has "supplied". I'm using it for consolidating large number of images into a single multipage tiff file with lossy jpeg compression.

I encountered this problem: When reading a large number of jpegs (~110-130,000) and splitting them into about 6 or 7 tiffs for writing (lossy jpeg), the write times for each tiff increases without a substantial difference in size, e.g., in seconds:
7.7722 22.6828 36.9034 51.3214 59.7900 74.0005 87.6450
The sizes of the tiffs are not increasing like that (they are all between 360 and 520MB).

Curiously, the next batch of jpegs that are loaded by another call to the function that splits then and calls your function start again from about 7 minutes and the time increases again, and so on.

What do you think?

16 Sep 2016 JWall

JWall (view profile)

The new version is working perfectly, thanks very much!

Comment only
14 Sep 2016 YoonOh Tak

YoonOh Tak (view profile)

Hi, JWall. I opened the target image file using an image viewing software and tried to append 200 frames. Then few seconds later, 'saveastiff' function stopped with error what you mentioned. So I added file opening error checking routines. Please retry using this new version. Thank you.

Comment only
13 Sep 2016 JWall

JWall (view profile)

Hello,
I am running into another problem recently - when I am saving multipage tiffs (using a for loop to go through the planes and using saveastiff to append the image for each plane), sometimes I get the error:
Error using tifflib
Unable to open TIFF file <my filename>

Error in Tiff (line 651)
obj.FileID = tifflib('open',filename,mode);

Error in saveastiff (line 230)
tfile = Tiff([fname, fext], 'r+');

I think it is some version of the problem described here:
http://blogs.mathworks.com/steve/2010/11/09/the-mystery-of-the-failing-tiff-append-loop/
However, closing internet explorer does not entirely fix the problem, just makes it less frequent. If you have any suggestions, that would be greatly appreciated, thanks!

Comment only
30 Aug 2016 YoonOh Tak

YoonOh Tak (view profile)

Hello, Mark. I fixed some codes. Please download the new version and let me know if it still slow. Thank you.

Comment only
29 Aug 2016 Mark

Mark (view profile)

For large (~4gb) tifs, somehow even this is still substantially slower than using Fiji to copy the image through memory into ImageJ and THEN save it. How is this possible??

Comment only
29 Aug 2016 YoonOh Tak

YoonOh Tak (view profile)

Hello, rjvyas. If a variable name of your image is 'example', you can save it using this command -> saveastiff(example, 'example.tif');

Comment only
29 Aug 2016 rjvyas

rjvyas (view profile)

how do I use this algorithm???

Comment only
28 Apr 2016 YoonOh Tak

YoonOh Tak (view profile)

Hello, JWall. I updated the function and it supports saving image to a sub-directory. Please check this new version. Thank you.

Comment only
26 Apr 2016 JWall

JWall (view profile)

I found this very helpful for saving multipage tiffs, thank you!
One small issue that I ran into:
I am trying to save multipage tiffs in a subfolder of my current directory. This works correctly when options.ask and options.append are set to true, but not when options.ask = false. I ended up adding the following on line 121 to solve this problem:
tappend = Tiff(path, 'r+');

Comment only
16 Mar 2016 Peter Quicke

Thank you very much, this solves the problem! Your update is much appreciated :)

Comment only
11 Mar 2016 YoonOh Tak

YoonOh Tak (view profile)

Hello, Peter Quicke.
'saveastiff' function make a temporary file to save data and the temporary file should be deleted before finish the function. I think there was some problem to delete your temporary file. Because it is impossible to make two file with same name in the same folder, your code could not open(make) a new temporary file.
Thus, I added some code to delete an existing temporary file before try to make a new temporary file.
I hope this helps you solve your problem.
Thank you.

Comment only
09 Mar 2016 Peter Quicke

Hello,

Thanks very much for this submission! I have been using it without problems for a while but have just stumbled onto a problem that I don't understand and was wondering if you could help me with it.

In certain folders Tifflib is unable to open open TIFF file "~$temporal.tif" and I am unable to save my file. This does not happen when the current folder is one step up or down on the folder path. Do you have any idea as to the cause of this? If I change the tempfile name then it can open a tiff fine. I have checked but there doesn't seem to be a locked tiff with the tempfile filename in the folders where it won't open.

Thanks very much!

06 Mar 2015 YoonOh Tak

YoonOh Tak (view profile)

And I recommend use 'options.message = true' code to check your error. For example,

=======================================
clear all;
u16 = uint16(rand(10, 10)*255);
rgb = uint8(rand(10, 10, 3)*255);

options.message = true;
options.color = true;
saveastiff(rgb, 'test.tif', options);
options.append = true;
% options.color = false;
saveastiff(u16, 'test.tif', options); % Error! 'u16' is not a color image. Add 'options.color = false' before this line.

tif = loadtiff('test.tif');
if (all(all(tif{2} == u16)) && all(all(all(tif{1} == rgb))))
disp('no problem');
else
disp('error');
end
=======================================

Comment only
06 Mar 2015 YoonOh Tak

YoonOh Tak (view profile)

Thank for your rating, Mr. Mailfert.
But I could not find a problem that you mentioned.

I have tested it using this code.

=======================================
clear all;
u16 = uint16(rand(10, 10)*255);
rgb = uint8(rand(10, 10, 3)*255);

saveastiff(u16, 'test.tif');
options.append = true;
options.color = true;
saveastiff(rgb, 'test.tif', options);

tif = loadtiff('test.tif');
if (all(all(tif{1} == u16)) && all(all(all(tif{2} == rgb))))
disp('no problem');
else
disp('error');
end
=======================================

Could you tell me a little more about your problem?

Comment only
05 Mar 2015 Sébastien MAILFERT

Hello,

this is really interesting and I'm currently using it for my application.
I have a problem to mix in one multiple frame different images.
I'm able to append in one file multiple images in uint16 format or multiple images in RGB.
I have to mix both types. How could I do?
Thanks for your help.
I used different options like append, color, etc. but when I append uint16 and RGB data, the file is not correct.
Thanks for your help.
Sébastien

21 Sep 2014 Eyal

Eyal (view profile)

Append only works when ask is enabled...

Comment only
15 Sep 2014 Urs Utzinger

Change/add following code for big tiff support in saveastiff.m. Big tiff uses 64 bit addressing and allows for files >2 Gbyte.

Comment Section:
% options.big
% : true or FALSE,
% use big tiff format

Argument parsing section:

if isfield(options, 'big') == 0
options.big = false;
end

Open output file section:

if ~options.append
if ispc
tempfile = '~$temporal.tif';
else
tempfile = '._temporal.tif';
end
s=whos('data');
if s.bytes > 2^32-1 || options.big
t = Tiff(tempfile, 'w8');
else
t = Tiff(tempfile, 'w');
end

18 Mar 2014 Dmitry Sorokin

08 Mar 2014 Jose Rosado

19 Oct 2013 Shalin Mehta

This function provides approx. 10x speed up on a windows machine as compared to imwrite(..'append') loop. But, on mac (I presume also on Unix) the call to fileattrib (fileattrib(tempfile, '+h +w', '', 's');) throws an exception. saveastiff catches this exception and deletes the temp file without saying anything.

The exception occurs because +h (hidden) attribute is not valid on mac. Removing +h and -h from the calls to fileattrib fixes the problem.

29 Nov 2012 YoonOh Tak

YoonOh Tak (view profile)

Yes, Jurgen. You need Matlab 2009b or later.

Comment only
29 Nov 2012 Jurgen

Jurgen (view profile)

Oh nvm I don't have the Tiff class :(

Comment only
29 Nov 2012 Jurgen

Jurgen (view profile)

Doens't work for me, using MATLAB 2008a. Dont get any error but there is no savefile in my current directory.

Comment only
21 Nov 2012 Weicheng Kuo

Fantastic performance!! :) Can't help but create an account to recommend it!

21 Aug 2012 Casey Ta

Very nice. I had to manually add support for PackBits, but this was very easy to do (compression tag value 32773). I did happen to notice one typo on line 202 where "optoins" should be "options".

15 Jun 2012 Andrew

Andrew (view profile)

So much faster than imwrite(foo, ; 'writemode','append') for large (500+ page) tiffs. Thank You!

16 May 2012 Mathew Thomas

Updates
19 Mar 2012 1.4

Support lossy JPEG Compression.
bug fixed.

06 Apr 2012 1.5

There was a bug in the example.
  [X,Y,Z] = peaks(100);
is modified to
  [X,Y,Z] = single(peaks(100));

09 May 2012 1.6

Parameter 'options' is added.

10 May 2012 1.8

bug fix

11 May 2012 1.9

Bug fix
Now you can append an image data to an existing tiff file.
And any type of data can be appended to an existing file.

11 May 2012 1.10

Bug fixed.
Now, it supports 'double' precision.

27 Aug 2012 1.11

Ttypographical error on line 202 : optoins -> options
Thank you, Casey Ta.

20 Nov 2012 1.12

Bug fix: It crashed when the file is already opened.

06 Sep 2013 1.16

bug fix

21 Oct 2013 1.18

Bug fix.
Thank you, Dr. Shalin Mehta.
I added some 'ispc' codes to avoid the exception on mac. But I'm sorry that I couldn't test this version because I don't have mac os.

16 Sep 2014 1.19

Bug fix and add 'big' option for BigTIFF format (Thanks to Urs Utzinger).

22 Sep 2014 1.20

There was a mistake in the version 2.5, and I fixed it. Thank you, Eyal.

10 Mar 2016 2.6

Now it supports 'uint64' and 'int64' data type.
Bug fixed: Temporary file will be deleted before creating new tiff file. (thanks to Peter Quicke)

11 Mar 2016 2.6

I uploaded an old version yesterday. It was my mistake.... This is a new version.

28 Apr 2016 3.0

Now you can save image to a sub directory.

28 Apr 2016 3.0

Now you can save image to a sub directory.

28 Apr 2016 3.0

Now you can save image to a sub directory.

10 May 2016 4.0

Now you can save a complex number image such as Fourier's coefficient image.
Pixels in a color image also can have complex numbers.
The fourth channel on a color image will be regarded as an alpha blending channel.

30 Aug 2016 4.1

Hello, Mark. I fixed my code a little bit. Please check this new version. I think it will be faster than before.

14 Sep 2016 4.2

Added a file opening error checking routine.

21 Sep 2016 4.3

Bug fix: RowsPerStrip of JPEG compression has to be a multiple of 16.

Contact us