Search code examples
pythonpython-3.xtagstiffgeotiff

How can I change or delete GeoTIFF-Tags?


I couldn't find a way, so far, to change GeoTiff-TAGs in my TIFF-file. My OS is Linux Lubuntu 18.04 and I'm using Python 3.x. Just EXIF-TAGs were possible to change via various approaches.

For both reading and writing the EXIF-TAGs, I could use e.g.:

  • command-line tool: exiftool
  • python-module: exifread
  • python-module: PIL
  • python-module: tifffile
  • python-module: skimage.external.tifffile

Especially the python-modules seem to be "blind on the eye" of GeoTiff-Tags, i.e. they read (and write) only the EXIF-TAGs, but not the GeoTiff-Tags. With exiftool, I can at least read and printout the GeoTiff-TAGs along with the other ones. For instance, a console output via exiftool of my TIFF-file, which includes the GeoTiff-Tags as well, would be:

Input:

exiftool -D -G -a -u -U -f "newfile.tif"

Output:

[ExifTool]          - ExifTool Version Number         : 10.80
[File]              - File Name                       : newfile.tif
[File]              - Directory                       : .
[File]              - File Size                       : 1503 kB
[File]              - File Modification Date/Time     : 2019:12:19 17:32:17+01:00
[File]              - File Access Date/Time           : 2019:12:19 17:32:17+01:00
[File]              - File Inode Change Date/Time     : 2019:12:19 17:32:17+01:00
[File]              - File Permissions                : rw-rw-r--
[File]              - File Type                       : TIFF
[File]              - File Type Extension             : tif
[File]              - MIME Type                       : image/tiff
[File]              - Exif Byte Order                 : Little-endian (Intel, II)
[File]              - Current IPTC Digest             : 79ffcf282ca6974ff99640a7421b40b7
[EXIF]            256 Image Width                     : 1148
[EXIF]            257 Image Height                    : 1337
[EXIF]            258 Bits Per Sample                 : 8
[EXIF]            259 Compression                     : Uncompressed
[EXIF]            262 Photometric Interpretation      : RGB Palette
[EXIF]            273 Strip Offsets                   : (Binary data 1390 bytes, use -b option to extract)
[EXIF]            274 Orientation                     : Horizontal (normal)
[EXIF]            277 Samples Per Pixel               : 1
[EXIF]            278 Rows Per Strip                  : 7
[EXIF]            279 Strip Byte Counts               : (Binary data 954 bytes, use -b option to extract)
[EXIF]            282 X Resolution                    : 1
[EXIF]            283 Y Resolution                    : 1
[EXIF]            284 Planar Configuration            : Chunky
[EXIF]            296 Resolution Unit                 : None
[EXIF]            305 Software                        : IMAGINE TIFF Support.Copyright 1991 - 1999 by ERDAS, Inc. All Rights Reserved.@(#)$RCSfile: etif.c $ $Revision: 1.11 $ $Date$
[EXIF]            320 Color Map                       : (Binary data 1536 bytes, use -b option to extract)
[EXIF]            339 Sample Format                   : Unsigned
[EXIF]          33550 Pixel Scale                     : 30 30 0
[EXIF]          33922 Model Tie Point                 : 0 0 0 1514925 1583985 0
[IPTC]             25 Keywords                        : word
[IPTC]              0 Application Record Version      : 4
[GeoTiff]           1 Geo Tiff Version                : 1.1.0
[GeoTiff]        1024 GT Model Type                   : Projected
[GeoTiff]        1025 GT Raster Type                  : Pixel Is Area
[GeoTiff]        1026 GT Citation                     : IMAGINE GeoTIFF Support.Copyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved.@(#)$RCSfile: egtf.c $ $Revision: 1.11.2.3 $ $Date: 2004/11/24 09:12:56EST $.Projection Name = USA_Contiguous_Albers_Equal_Area_Conic_USGS_version.Units = meters.GeoTIFF Units = meters
[GeoTiff]        2048 Geographic Type                 : NAD83
[GeoTiff]        3072 Projected CS Type               : User Defined
[GeoTiff]        3073 PCS Citation                    : IMAGINE GeoTIFF Support.Copyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved.@(#)$RCSfile: egtf.c $ $Revision: 1.11.2.3 $ $Date: 2004/11/24 09:12:56EST $.Projection = Albers Conical Equal Area
[GeoTiff]        3074 Projection                      : User Defined
[GeoTiff]        3075 Proj Coord Trans                : Albers Equal Area
[GeoTiff]        3076 Proj Linear Units               : Linear Meter
[GeoTiff]        3078 Proj Std Parallel 1             : 29.5
[GeoTiff]        3079 Proj Std Parallel 2             : 45.5
[GeoTiff]        3081 Proj Nat Origin Lat             : 23
[GeoTiff]        3082 Proj False Easting              : 0
[GeoTiff]        3083 Proj False Northing             : 0
[GeoTiff]        3088 Proj Center Long                : -96
[Composite]         - Image Size                      : 1148x1337
[Composite]         - Megapixels                      : 1.5

Then, I tried like to change/delete e.g. the GeoTiff-TAG "Projection", which throws the following warning message without changing anything: Input:

exiftool "-Projection=" "newfile.tif"

Output:

Warning: Sorry, Projection is not writable. Nothing to do.

On my search on the internet I've found other libraries and packages, which perhaps could help me out, but so far no avail, as I didn't find documentation, or it didn't work:

  • libtiff (via command tiffset, such as "tiffset -s Tag-Number Tag-Value dst-file", which changes/adds only EXIF-Tags, but doesn't touch the GeoTIFF-Tags)
  • libgeotiff
  • gdal_edit, gdal_translate (or gdal in general)

As for the latter approach, gdal_edit and gdal_translate, I tried the following with no effect (even though there was no error-message whatsoever):

gdal_edit.py -mo "3075=Custom" "newfile.tif"
gdal_edit.py -mo "ProjCoordTrans=Custom" "newfile.tif"
gdal_translate -mo "3075=Custom" "newfile.tif" "newfile_2.tif"
gdal_translate -mo "ProjCoordTrans=Custom" "newfile.tif" "newfile_2.tif"

As you can see, in the example, I tried to modify the GeoTIFF-Tag number 3075, named "ProjCoordTrans" to a costum string. When carrying any of these 4 commands, no error was thrown, but checking afterwards the TIFF-Tags via

exiftool -D -G -a -u -U -f -s "newfile.tif"

I found the same TAG remained still unchanged.

I'd like to know if there is a possibility to change GeoTiff-Tags. There must be a possibility.


Solution

  • I've found an answer on the project-page of exiftool itself. Hereafter, I'll summarize what I found out with the kind help of the page-author Phil Harvey.

    To copy all GeoTiff tags from one file to another, do this:

    exiftool -tagsfromfile SRCFILE -GeoTiffDirectory -GeoTiffDoubleParams -GeoTiffAsciiParams DSTFILE
    

    That does the trick. I assume that those pseudo-TAGs are split-up by exiftools in all sub-GeoTiff-TAGs, because other tools in python print these out as TAGs with their associated numbers. Python packages which are able to display these general 3 Geotiff-TAGs

    • ('34735') 'GeoKeyDirectoryTag'
    • ('34736') 'GeoDoubleParamsTag'
    • ('34737') 'GeoAsciiParamsTag'

    are for example:

    import PIL
    import tifffile as tf
    from skimage.external import tifffile as sk_tf
    

    An example output using PILLOW (PIL) via my python script applied on an example TIFF would be:

    ...
    ** GENERIC APPROACH USING PILLOW-package **
    
    TAG number: '254'
    TAG name: 'NewSubfileType'
    TAG value: '(0,)'
    
    TAG number: '256'
    TAG name: 'ImageWidth'
    TAG value: '(2388,)'
    
    TAG number: '257'
    TAG name: 'ImageLength'
    TAG value: '(1651,)'
    
    TAG number: '258'
    TAG name: 'BitsPerSample'
    TAG value: '(8,)'
    
    TAG number: '259'
    TAG name: 'Compression'
    TAG value: '(1,)'
    
    TAG number: '262'
    TAG name: 'PhotometricInterpretation'
    TAG value: '(1,)'
    
    TAG number: '270'
    TAG name: 'ImageDescription'
    TAG value: '('{"shape": [1651, 2388]}',)'
    
    TAG number: '274'
    TAG name: 'Orientation'
    TAG value: '(1,)'
    
    TAG number: '277'
    TAG name: 'SamplesPerPixel'
    TAG value: '(1,)'
    
    TAG number: '278'
    TAG name: 'RowsPerStrip'
    TAG value: '(1651,)'
    
    TAG number: '282'
    TAG name: 'XResolution'
    TAG value: '((1, 1),)'
    
    TAG number: '283'
    TAG name: 'YResolution'
    TAG value: '((1, 1),)'
    
    TAG number: '284'
    TAG name: 'PlanarConfiguration'
    TAG value: '(1,)'
    
    TAG number: '296'
    TAG name: 'ResolutionUnit'
    TAG value: '(1,)'
    
    TAG number: '305'
    TAG name: 'Software'
    TAG value: '('tifffile.py',)'
    
    TAG number: '339'
    TAG name: 'SampleFormat'
    TAG value: '(1,)'
    
    TAG number: '33550'
    TAG name: 'ModelPixelScaleTag'
    TAG value: '(30.0, 30.0, 0.0)'
    
    TAG number: '33922'
    TAG name: 'ModelTiepointTag'
    TAG value: '(0.0, 0.0, 0.0, 737125.0, 4328658.0, 0.0)'
    
    TAG number: '34735'
    TAG name: 'GeoKeyDirectoryTag'
    TAG value: '(1, 1, 0, 15, 1024, 0, 1, 1, 1025, 0, 1, 1, 1026, 34737, 266, 0, 2048, 0, 1, 4269, 3072, 0, 1, 32767, 3073, 34737, 197, 266, 3074, 0, 1, 32767, 3075, 0, 1, 11, 3076, 0, 1, 9001, 3078, 34736, 1, 0, 3079, 34736, 1, 1, 3081, 34736, 1, 2, 3082, 34736, 1, 3, 3083, 34736, 1, 4, 3088, 34736, 1, 5)'
    
    TAG number: '34736'
    TAG name: 'GeoDoubleParamsTag'
    TAG value: '(29.5, 45.5, 23.0, 0.0, 0.0, -96.0)'
    
    TAG number: '34737'
    TAG name: 'GeoAsciiParamsTag'
    TAG value: '('IMAGINE GeoTIFF Support\nCopyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile: egtf.c $ $Revision: 1.11.2.3 $ $Date: 2004/11/24 09:12:56EST $\nProjection Name = USA_Contiguous_Albers_Equal_Area_Conic_USGS_version\nUnits = meters\nGeoTIFF Units = meters|IMAGINE GeoTIFF Support\nCopyright 1991 - 2001 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile: egtf.c $ $Revision: 1.11.2.3 $ $Date: 2004/11/24 09:12:56EST $\nProjection = Albers Conical Equal Area|',)'
    ...
    

    To change the Projection tag alone, you would currently have to manually edit the GeoTiffDirectory data.

    First write the (binary) data to a file:

    exiftool -geotiffdirectory -b FILE.tif > out.dat
    

    Then find the offset of e.g. the Projection value, like:

    exiftool FILE.tif -v3 | grep -A 2 Projection -
      | 9)  Projection = 16017
      |     - Tag 0x0c02 (2 bytes, int16u[1]):
      |         0056: 3e 91                                           [>.]
    

    --> Edit bytes 0x56 and 0x57 in out.dat to change to whatever projection you want, then put the modified GeoTiff directory back into the TIFF file:

    exiftool "-geotiffdirectory<=out.dat" FILE.tif
    

    Nevertheless, it is important to note, that changing the 3 crucial summarizing GeoTIFF-Tags, instead of trying to manipulate one of the single GeoTIFF-TAGs via modifying the above-mentioned binary-file and reassign it to the TIFF in question, could be more effective.

    For the sake of completion, these 3 GeoTIFF-Tags were:

    • ('34735') 'GeoKeyDirectoryTag'
    • ('34736') 'GeoDoubleParamsTag'
    • ('34737') 'GeoAsciiParamsTag'

    Nevertheless, it could be possible that by changing just one specific GeoTIFF-Tag within the binary-file is also going to update as a result the 3 crucial GeoTIFF-summary-Tags in new TIFF. I haven't tried that out yet.

    If you have to add some additional information or experiences with these approaches, which work for you etc., let me know.

    Cheers