Changing or deleting GeoTiff-TAGs

Started by AndyLuckert, December 19, 2019, 12:23:02 PM

Previous topic - Next topic

AndyLuckert

Dear community and author Phil Harvey,

I'm using Linux Lubuntu 18.04 with exiftool command line in order to modify TIFF-Tags of a land cover classification GeoTIFF-file.

As the Python libraries

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

don't even list the GeoTiff tags, as they are "blind on that eye", I found that exiftool lists, but cannot change them.


The output of my example file, using exiftool in the terminal, is:

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


Now, I'd like to change/delete 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.

Next, I found the following documentation of this very webpage:
https://exiftool.org/TagNames/GeoTiff.html

It states, among other details, the following:
QuoteGeoTIFF tags are not writable individually, but they may be copied en mass via the block tags GeoTiffDirectory, GeoTiffDoubleParams and GeoTiffAsciiParams.

Is there any possibility to change/rename/delete a GeoTiff-TAG of choice via command line exiftools as stated above in my attempt?
I'm quite desparate already, since I've invested a lot of time in finding a possiblity, but so far no avail.

Thanks in advance for helping me out.
Kind regards,
Andreas

Phil Harvey

#1
Hi Andreas,

To delete all GeoTiff stuff, do this:

exiftool "-geotiff*=" FILE

But to change the Projection tag alone, you would currently have to manually edit the GeoTiffDirectory data:

First write the data to file:

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

Then find the offset of the Projection value, eg)

% 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

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

AndyLuckert

Hey Phil,

thanks for your quick help!

I've tried to overwrite simply the entire GeoTIFF-directory of the target file from another model TIFF.

# Definition of Python-function implementing exiftools
def overwrite_GeoTIFF_Tags_of_TIFF_from_another_model_TIFF(
        input_TIFF=None,
        model_TIFF=None,
        GeoTIFF_Tag_binary_file_output_basename=None,
        linux_dir_sep="/"):

    # Give either generic name, or accept custom name passed by the user
    if GeoTIFF_Tag_binary_file_output_basename is None:
        GeoTIFF_Tag_binary_file_output_basename = "GeoTIFF_Tags_binary_file"
    # Create a proper output filename for the extracted GeoTIFF-Tag binary data file
    GeoTIFF_binary_filepath = "{dir}{ls}{bn}.dat".format(dir=model_TIFF.rsplit(linux_dir_sep, 1)
        [0], ls=linux_dir_sep, bn=GeoTIFF_Tag_binary_file_output_basename)

    # * Export entire GeoTIFF-TAG information from model TIFF into a binary file *
    # NOTE on parameter "-b": needs to be there to export it as binary format
    # Define bash-terminal command string for sending to the console later on
    bash_str = """exiftool -geotiffdirectory -b {m} > {binary}""".format(
        m=model_TIFF, binary=GeoTIFF_binary_filepath)
    # Carry out command in bash-terminal externally
    subprocess.check_call(bash_str, shell=True)

    # * Overwrite ALL GeoTIFF-TAG info of main TIFF *
    # NOTE on command-outputs: produces another output with the same name + "_original" in order to save the TIFF-file before changing it
    # Define bash-terminal command string for sending to the console later on
    bash_str = """exiftool "-geotiffdirectory<={binary}" {i}""".format(
        binary=GeoTIFF_binary_filepath, i=input_TIFF)
    # Carry out command in bash-terminal externally
    subprocess.check_call(bash_str, shell=True)



Unfortunately, it seems that the overwriting result is incomplete.
I revealed this via employing exiftool for examination like so:
exiftool -D -G -a -u -U -f -s example.tif

The GeoTIFF-Tags from the model file are:
Quote[GeoTiff]           1 GeoTiffVersion                  : 1.1.0
[GeoTiff]        1024 GTModelType                     : Projected
[GeoTiff]        1025 GTRasterType                    : Pixel Is Area
[GeoTiff]        1026 GTCitation                      : 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 GeographicType                  : NAD83
[GeoTiff]        3072 ProjectedCSType                 : User Defined
[GeoTiff]        3073 PCSCitation                     : 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 ProjCoordTrans                  : Albers Equal Area
[GeoTiff]        3076 ProjLinearUnits                 : Linear Meter
[GeoTiff]        3078 ProjStdParallel1                : 29.5
[GeoTiff]        3079 ProjStdParallel2                : 45.5
[GeoTiff]        3081 ProjNatOriginLat                : 23
[GeoTiff]        3082 ProjFalseEasting                : 0
[GeoTiff]        3083 ProjFalseNorthing               : 0
[GeoTiff]        3088 ProjCenterLong                  : -96


The previous GeoTIFF-Tags (before changing them) of the main TIFF are:
Quote[GeoTiff]           1 GeoTiffVersion                  : 1.1.0
[GeoTiff]        1024 GTModelType                     : Projected
[GeoTiff]        1025 GTRasterType                    : Pixel Is Area
[GeoTiff]        1026 GTCitation                      : ETRS89_UTM_zone_30N
[GeoTiff]        2048 GeographicType                  : User Defined
[GeoTiff]        2049 GeogCitation                    : GCS Name = GCS_ETRS_1989|Datum = ETRS_1989|Ellipsoid = GRS_1980|Primem = Greenwich|
[GeoTiff]        2050 GeogGeodeticDatum               : User Defined
[GeoTiff]        2054 GeogAngularUnits                : Angular Degree
[GeoTiff]        2056 GeogEllipsoid                   : User Defined
[GeoTiff]        2057 GeogSemiMajorAxis               : 6378137
[GeoTiff]        2059 GeogInvFlattening               : 298.257222101
[GeoTiff]        2061 GeogPrimeMeridianLong           : 0
[GeoTiff]        3072 ProjectedCSType                 : User Defined
[GeoTiff]        3074 Projection                      : UTM zone 30N
[GeoTiff]        3076 ProjLinearUnits                 : Linear Meter

After the changing the GeoTIFF-Tags of the TIFF-file in queston are the following:
Quote[GeoTiff]           1 GeoTiffVersion                  : 1.1.0
[GeoTiff]        1024 GTModelType                     : Projected
[GeoTiff]        1025 GTRasterType                    : Pixel Is Area
[GeoTiff]        2048 GeographicType                  : NAD83
[GeoTiff]        3072 ProjectedCSType                 : User Defined
[GeoTiff]        3074 Projection                      : User Defined
[GeoTiff]        3075 ProjCoordTrans                  : Albers Equal Area
[GeoTiff]        3076 ProjLinearUnits                 : Linear Meter
[GeoTiff]        3078 ProjStdParallel1                : 6378137
[GeoTiff]        3079 ProjStdParallel2                : 298.257222101
[GeoTiff]        3081 ProjNatOriginLat                : 0


I don't know what else to do, since for some reason the transferring of the GeoTIFF-Tags doesn't seem to extract and/or insert all TAGs available in the initial model TIFF.

Thanks in advance for further advice.


PS:
I attached the files in question to this post.
- Target file to which the GeoTIFF-Tags shall be transferred: Denia_CORINE_CODE_18_reclass_NLCD92_mod_TAGs.tif
- Model file from which the GeoTIFF-Tags are extracted: AERSURFACE_test_raster.tif

Phil Harvey

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

exiftool -tagsfromfile SRCFILE -GeoTiffDirectory -GeoTiffDoubleParams -GeoTiffAsciiParams DSTFILE

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

AndyLuckert

Quote from: Phil Harvey on December 20, 2019, 09:54:19 PM
To copy all GeoTiff tags from one file to another, do this:

exiftool -tagsfromfile SRCFILE -GeoTiffDirectory -GeoTiffDoubleParams -GeoTiffAsciiParams DSTFILE

- Phil

--> Thanks, 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|',)'
...

AndyLuckert

Quote from: Phil Harvey on December 19, 2019, 12:26:30 PM
To change the Projection tag alone, you would currently have to manually edit the GeoTiffDirectory data:

First write the data to file:

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

Then find the offset of the Projection value, eg)

% 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

- Phil

Dear Phil,

when I realized that the mentioned output file "out.dat" is a binary file (not a text-file), I wondered how I could actually change or edit these bytes 0x56 and 0x57 to another projection?
Quote--> Edit bytes 0x56 and 0x57 in out.dat to change to whatever projection you want
So far, I only know how to automate (plain) text-file editing via python for example, but editing binary files is new to me.
In a text-file, I'd just replace the string assigned to the TAG with the desired string (or characters respectively; and if it were a number, insert a custom float or integer value).

I'd be glad if you could give me a hint.
Thanks in advance.

Phil Harvey

Hi Andy,

I use my own scripts to do stuff like this...  But Google is your friend -- you will probably be able to find an app out there with this ability.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

AndyLuckert