Skip to content

GeoTiff tags weren't being saved out until I added the GeoTiff tags to Tiff_DirInfo.cs #126

@stewienj

Description

@stewienj

I tried to create a Tiff file with some GeoTiff tags, but the GeoTiff tags weren't being saved out.

This was fixed by adding the following TiffFieldInfo objects to the tiffFieldInfo field in Tiff_DirInfo.cs, at the appropriate positions to maintain order:

new TiffFieldInfo(TiffTag.GEOTIFF_MODELPIXELSCALETAG, -3, -3, TiffType.DOUBLE, FieldBit.Custom, true, true, "GeoTiffModelPixelScale"),
new TiffFieldInfo(TiffTag.GEOTIFF_MODELTIEPOINTTAG, -3, -3, TiffType.DOUBLE, FieldBit.Custom, true, true, "GeoTiffModelTiePoint"),
new TiffFieldInfo(TiffTag.GEOTIFF_GEOKEYDIRECTORYTAG, -3, -3, TiffType.SHORT, FieldBit.Custom, true, true, "GeoTiffGeoKeyDirectory"),
new TiffFieldInfo(TiffTag.GEOTIFF_GEOASCIIPARAMSTAG, -3, -3, TiffType.ASCII, FieldBit.Custom, true, true, "GeoTiffGeoAsciiParams"),

Here's some sample code based on your Black and White sample for writing out a GeoTiff that should appear in the middle of Australia when loaded in a mapping program:

public record TiffTagDataType<DataType>(int TagId, DataType[] Data)
{
  public object[] AsObjectArray() => [TagId, Data];
}

public class TiffBlackAndWhiteWithGeo
{
  public static void Create(string fileName)
  {
    const int width = 32;
    const int height = 100;
    const int samplesPerPixel = 1;
    const int bitsPerSample = 8;

    var GEOTIFF_MODELPIXELSCALETAG = new TiffTagDataType<double>(
      // Size of data
      3,
      // East/West degrees per pixel, North/South degrees per pixel, 0
      [1.0/width, 1.0/height, 0.0]
    );

    var GEOTIFF_MODELTIEPOINTTAG = new TiffTagDataType<double>(
      // Size of data
      6,
      [
        // Just leave as zeros
        0.0, 0.0, 0.0,
        // West Edge, North Edge, 0.0
        135.0, -25.0, 0.0, 0.0
      ]
    );

    // This specifies what coordinate system we are using and some other meta data. Didn't look up all of it.
    // Note the data is in groups of 4
    var GEOTIFF_GEOKEYDIRECTORYTAG = new TiffTagDataType<ushort>(
      // Size of data
      32,
      [
        1, 1, 0, 7,
        1024, 0, 1, 2,
        1025, 0, 1, 1,
        2048, 0, 1, 4326,
        2049, 34737, 7, 0,
        2054, 0, 1, 9102,
        2057, 34736, 1, 1,
        2059, 34736, 1, 0
      ]
    );

    var GEOTIFF_GEOASCIIPARAMSTAG = new TiffTagDataType<byte>(
      // Size of data, which is 1 more than the data for some reason when adding ascii strings
      8,
      // The | character is converted to a zero later on
      "WGS 84|"u8.ToArray()
    );

    var GDAL_NODATA = new TiffTagDataType<byte>(
      // Size of data
      1,
      // A pixel value of zero means no data when we add a zero here
      [0]
    );

    using (Tiff output = Tiff.Open(fileName, "w"))
    {
      output.SetField(TiffTag.IMAGEWIDTH, width / samplesPerPixel);
      output.SetField(TiffTag.SAMPLESPERPIXEL, samplesPerPixel);
      output.SetField(TiffTag.BITSPERSAMPLE, bitsPerSample);
      output.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
      output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
      output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
      output.SetField(TiffTag.ROWSPERSTRIP, output.DefaultStripSize(0));

      output.SetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG, GEOTIFF_MODELPIXELSCALETAG.AsObjectArray());
      output.SetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG, GEOTIFF_MODELTIEPOINTTAG.AsObjectArray());
      output.SetField(TiffTag.GEOTIFF_GEOKEYDIRECTORYTAG, GEOTIFF_GEOKEYDIRECTORYTAG.AsObjectArray());
      output.SetField(TiffTag.GEOTIFF_GEOASCIIPARAMSTAG, GEOTIFF_GEOASCIIPARAMSTAG.AsObjectArray());

      // compression is optional
      output.SetField(TiffTag.COMPRESSION, Compression.ADOBE_DEFLATE);

      // fill samples array
      byte[][] buffer = new byte[height][];
      for (int j = 0; j < height; j++)
      {
        buffer[j] = new byte[width];
        for (int i = 0; i < width; i++)
          buffer[j][i] = (byte)(j * width + i);
      }

      for (int j = 0; j < height; ++j)
        output.WriteScanline(buffer[j], j);
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions