File Exchange

image thumbnail


version (24 KB) by Jimmy Shen
Write a 2D or 3D array to a single or multi-band GeoTIFF file


Updated 04 Dec 2012

View Version History

View License

This program can write a 2D or 3D array to a single or multi-band GeoTIFF file. For more information and examples, please visit:
or type: help geotiffwrite

MATLAB's Mapping Toolbox only provides a "geotiffread" function, but it does not have a "geotiffwrite" function (Note). This is the MATLAB program to write a 2D or 3D array to a single or multi-band GeoTIFF file, where data can be either 1-bit monochrome data (i.e. binary or bilevel), 8-bit unsigned integer, 16-bit signed / unsigned integer, 32-bit signed integer, or 32-bit floating point.

Note: Starting from version R2011a, MATLAB also provides its own "geotiffwrite" function

This program is based on GeoTIFF Format Specification under:

It does not need MATLAB's Mapping Toolbox, or any other library.

[option bbox] = make_option([bbox]);
geotiffwrite(filename, bbox, image, [bit_depth, option]);

For more information on arguments and detail examples, please visit:
or type: help geotiffwrite

Cite As

Jimmy Shen (2021). geotiffwrite (, MATLAB Central File Exchange. Retrieved .

Comments and Ratings (35)

Sven Briels

Hi everybody, I have a question about the colormap of geotiffwrite and how to use it with a specific range of values.
So, I have a manual colormap that works in the sense that it gives a somewhat correct output tiff. It has dimensions 256x3 and is filled with integers ranging from 0 to 256^2-1, all good. The output though, does not have the exact coloring which I would like it to have and I suspect that has something to do with the specific value-to-color mapping.

What I would like to do is map my values, which generally range from 0 to about 1300 with a few outliers above 1300, to a colormap with a specific range, say [0,1300], allowing the outliers to assume the color of the limit value of 1300. This is all perfectly possible with "colormap" and "caxis" in Matlab, but how to do it with geotiffwrite? The reason I want the values to be pinned down is that I need this function for thousands of tiffs, all with different maximum values (might be 1100 or 1400 even) and the coloring needs to be consistent. It is all very understandable if you consider the benefits of using "caxis".

How to do this with geotiffwrite? All help is welcome.


Has anyone been able to compile the geotiff in local projected coordinates? I'm having a hard time handling the option box to do that.

Thara C.S

hello sir,
how to convert the hdf5 file into geotiff file format?

Daniel Moran

Potentially helpful resource - Matlab can write matrices of double to BigTiff files:
See the "BigTiff" section.

I wrote a large whole-world image projected in Mollweide EPSG:54009 by writing the data out as a 64bit BigTIFF then using GDAL to add the Geo tags to the tiff to make it a GeoTiff

bt=Tiff('myfile.tif','w8'); % 'w8' means use BigTiff
tags.ImageLength = size(DATA,1);
tags.ImageWidth = size(DATA,2);
tags.Photometric = Tiff.Photometric.MinIsBlack; % How it should be displayed visually
tags.BitsPerSample = 64; % 64 for Doubles, 32 for singles
tags.SamplesPerPixel = 1; % This means greyscale image, not an RGB image
tags.TileWidth = 128;
tags.TileLength = 128;
tags.SampleFormat = Tiff.SampleFormat.IEEEFP;
tags.Compression = Tiff.Compression.LZW; % See Tiff.Compression for other options here
tags.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tags.Software = 'MATLAB';
setTag(bt, tags);
write(bt, M);

system('gdal_translate -co "NUM_THREADS=ALL_CPUS" -co "COMPRESS=LZW" -a_srs EPSG:54009 -a_ullr -18040095.3812882 9020047.84316439 18040095.3812882 -9020047.84316439 myfile.tif result_goetiff.tif')

Paresh Shirsath


I have a Matlab grid file which we I have tried converting into GeoTIFF file issue here is the image is 90degree rotated and I have tried changing projection it has not worked..can anyone tell me how make_option works? and why is the image rotated

Sharon Veerayah

Do i need a special toolbox to access geotiffread and geotiffwrite?
I can't find either using help geotiffread or write.
I get this error: Undefined function 'geotiffread'
I am using R2014a

Thank you.

Yann Marcon


sorry i just realized my mistake. I read your code too fast and kept using -8 for 8-bit unsigned integer instead of 8 (i thought that the 'minus' sign meant unsigned).

Everything works fine now. Thanks again for this great piece of work!

Yann Marcon

Jimmy, thanks for your answer.

I got confused because the code runs into an error at line 1108 when the bit depth is set to -8. This seems to be because this case is not considered at lines 828-837, and the 'ifd.SampleFormat' variable is not created.
However, if i replace line 831 with 'case {-8, 8, -16}' then the code seems to run just fine.

Is it correct or did i miss something?


Jimmy Shen

No, it is not a typo.

"bit_depth" value -16 & -32 were designed to expand datatype to "16-bit unsigned integer" & "32-bit signed integer".

If "bit_depth" is -8, it will be treated as 8 anyway, since only abstract value is considered. However, if it is 1 or -1, according to TIFF Revision 6.0 (Final-June 3, 1992), "SampleFormat" field has to be set to "undefined data format", since it is binary monochrome data.

If you look further down a little bit to line 932, you will find how I write data strip based on "bit_depth" value.

Yann Marcon

Hi Jimmy,

Thanks for the great code! It's really useful for those who have not switched to the new Matlab version.

I just would like to suggest a correction. I'm not sure but I think that there is a typo at line 829. Shouldn't it be 'case {1, -8}' instead of 'case {1, -1}' ?


Jimmy Shen

Please check:

You need to add:

option.ColorMap [Nx3 array]

Where N = 2^bit_depth, and bit_depth can only be 8 or 16. Values in option.ColorMap range from 0 to 65535, and value 0 in image points to the first row in the ColorMap. Columns in option.ColorMap are [R G B]. Black is represented by [0 0 0], and white is represented by [65535 65535 65535].

Val Schmidt

I'm having some trouble with your code and need some advice. I'm trying to read a JPEG image, and write it as a GeoTiff. Specifically, I'm unable to properly specify a colormap to retain the color in the resulting tif. I suspect, I simply don't understand how to properly specify the "options".

I'm not explicitly specifying a colormap (see code snippet below) and the resulting tiff is black and white (from an original color image).

I've tried using rgb2ind to create a colormap and apply it and I either get an unreadable image or a black and white one whose colors are scrambled.

Do you have any suggestions on how to do this properly?


% Read the image
I = imread('inputimage,jpg');
outfile = 'outputimage.tif');

% Set the options:
option.GTModelTypeGeoKey = 1;
option.ModelTiepointTag = [0, 0, 0, P(1,:),...
I_info.Height, 0,0, P(2,:),...
I_info.Height, I_info.Width, 0, P(3,:),...
0, I_info.Width, 0, P(4,:)];
option.GeogEllipsoidGeoKey = 7030; % WGS-84
option.PCSCitationGeoKey = ['UTM Zone ' zone ' with WGS84'];

if zone(end) >= 'N'
option.ProjectedCSTypeGeoKey = str2double(['326' zone(1:2)]);
option.ProjectedCSTypeGeoKey = str2double(['327' zone(1:2)]);

% Write the file:


thanks for this export option! It helps sharing my MatLab data with colleagues that do not use MatLab, but ArcGIS, a lot !

Kyle Mayer

Jesse Angle

In order to make this code fully support the ModelTransformationTag the following changes are necessary:

line 873: comment out
error('ModelPixelScale is required...');

as this isn't necessarily a true statement and will cause problems when trying to use only the ModelTransformationTag.

line 1213 - 1214:
fwrite(fid, gifd.ModelPixelScaleTag,'double'); and
fwrite(fid, gifd.ModelTiePointTag, 'double');

should be surrounded by
if isfield(gifd,'Model...Tag')


statements for when these tags are not being used as is the case with ModelTransformationTag.

Finally, add in the code that actually writes the ModelTransformationTag portion (previously missing). Mine looks like this:

if isfield(gifd,'ModelPixelScaleTag')
if isfield(gifd,'ModelTiePointTag')
if isfield(gifd,'ModelTransformationTag')

That being said, great work Jimmy getting this put together and thank you for your efforts.

Simon Lind

thank you very much Jimmy

Jimmy Shen

You need to use MATLAB's geotiffread to read L7 file into matrix, with all attributes. Then find out the index of your sub-region, and assign the sub-region to a new matrix. You can now use the make_option option in my package to select optional fields. However, you need to match the attributes that you read, and select the correct fields by yourself in order to create the optional fields to be used in my geotiffwrite. Since I don't have Mapping toolbox, I am afraid that I cannot provide you with more details.

Simon Lind

thank you for your response... i'm trying to select a region of a Landsat 7 geotiff image and then to save it with all its atributes. Please, how can I select the rectangular window?

Jimmy Shen

My geotiffwrite can only write a rectangular dataset into the file. As long as your sub-region is a rectangular dataset, you should be able to write it into a separate file.

Simon Lind

there is possible to select a sub-region of a geotiff image? i'm trying to do that but it seems not possible

Jimmy Shen

MATLAB finally has its own "geotiffwrite" function. So I suggest you use its geotiffread / geotiffwrite pair to load your Antarctica background, and superimpose your ship track data on top, and then re-write the entire data into GeoTIFF format using Matlab's geotiffwrite function.

I am currently no longer working in GeoScience field, so I am afraid that I cannot provide you with more useful advise.


Hi Jimmy, I found your post very informative, so I was hoping you could help me with a problem. I'm having issues attempting to plot a ship track on top of an already made geotiff image from Antarctica. The issue i believe is that it is stereographic, so i cannot use geotiff2mstruct. I am able to get the track on the ice image using profwd however the track is not exactly in the right spot. Also I cannot figure out how to get the latitude and longitude on the axes, the file has intrinsic or world x,y. Any advice?


Thanks for the fast response. I changed the colormap to include 256 elements and got it working. Seems to be a very useful script although it requires some troubleshooting with the 'option' inputs. Thank you!

Jimmy Shen

Please notice that the values in colormap range from 0 to 65535 (instead of from 0 to 1). So black is represented by [0 0 0], and white is represented by [65535 65535 65535]. If you put [1 1 1], it will be black. Please see more details from my web site:


I've been playing around with this code for a bit, but I'm having trouble with colormaps. If I use a standard colormap (which I am currently using to write standard tifs of my data), I get a solid black image. Any advice of support on the specific data format/colormap format required to successfully created a colored geotiff?

Jimmy Shen

If Model Type is "projected", you cannot use "bbox" variable directly, and you have to use "make_option.m" program to generate "option" variable.


great program. If the Model Type is not geographic, it clears the bbox variable ? My model type is "projected". So what should happen there? Thanks Matt


Excelent job! Works with Octave too. Just replace '&' with '&&' in lines 257 and 1165.

Jimmy Shen

Hi David:

SRTM (Shuttle Radar Topography Mission) data are nothing but Big-Endian, 16-bit Signed Integer binary numbers with either in 1201x1201 (SRTM3) or in 3601x3601 (SRTM1) dimension. You can simply use the following script to do the job:

function srtm=load_srtm(fn)
if length(srtm.dat)==1442401
srtm.dat=reshape(srtm.dat,[1201 1201]);
elseif length(srtm.dat)==12967201
srtm.dat=reshape(srtm.dat,[3601 3601]);

Please let me know if you encounter any problem.


David Davenish

Very helpful program, Thank you!

I have a question though, where can I find the "load_srtm" command that you exampl in link in "Description"?

Jimmy Shen

Hi David:

Thanks for you comments and rating.

Yes, you can use some of the fields contents returned by geotiffinfo to provide information for my option struct when you run the "make_option.m" program. However, please be careful, since my struct fields are DIRECTLY correspond to GeoTIFF Format Specification (like IDL software does); while struct fields from geotiffinfo in MATLAB software are NOT DIRECTLY correspond to GeoTIFF Format Specification. Here's a simple example: you can use geotiffinfo.TiePoints.WorldPoints for TiepointXYZ; but you cannot use geotiffinfo.TiePoints.ImagePoints for TiepointIJK.

I have just submitted 1-bit GeoTIFF support, so please come back in 2~3 days to see if they make my program available for you.



Great capability that Matlab has needed for a long time. I found that I can use the struct returned by geotiffinfo as the option struct for the input. I'd like to write a 1-bit geotiff. Any pointers would be appreciated.


MATLAB has been needing this for years. Thanks Jimmy. I really like the flexibility of this program.


MATLAB Release Compatibility
Created with R11.1
Compatible with any release
Platform Compatibility
Windows macOS Linux

Community Treasure Hunt

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

Start Hunting!