You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中读取存储float32高程值的非分块GeoTIFF像素数据

在C#(Unity)中读取非分块Float32 GeoTIFF高程值

目标GeoTIFF属性

  • 灰度格式
  • 存储float32类型数值
  • 非分块结构

Python参考实现

tiffArray = numpy.array(tiffImage)
elevation = tiffArray[0,0] # 返回值:39.66m

问题背景

尝试过libTiff库,但多数方案针对分块GeoTIFF,且因底层字节/二进制解码知识不足遇到无法排查的错误;GDAL难以集成到Unity,不考虑作为替代方案。


解决方案:使用LibTiff.Net实现

LibTiff.Net是纯.NET的TIFF处理库,适配Unity环境,针对非分块(条带存储)的Float32 GeoTIFF可以直接读取数据。

1. 集成到Unity

通过NuGet下载LibTiff.Net,或直接获取适配.NET Standard 2.0的编译DLL,将其放入Unity项目的Assets/Plugins目录中。

2. 读取高程值的代码实现

using System;
using LibTiff.Net;
using UnityEngine;

public class GeoTiffElevationReader : MonoBehaviour
{
    [SerializeField] private string tiffFilePath; // 赋值为GeoTIFF文件路径

    private void Start()
    {
        ReadTargetElevation();
    }

    private void ReadTargetElevation()
    {
        using (Tiff tiff = Tiff.Open(tiffFilePath, "r"))
        {
            if (tiff == null)
            {
                Debug.LogError("无法打开目标GeoTIFF文件");
                return;
            }

            // 获取图像元数据
            int width = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
            int bitsPerSample = tiff.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
            int samplesPerPixel = tiff.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
            int sampleFormat = tiff.GetField(TiffTag.SAMPLEFORMAT)[0].ToInt();
            int rowsPerStrip = tiff.GetField(TiffTag.ROWSPERSTRIP)[0].ToInt();

            // 验证格式是否符合要求
            if (bitsPerSample != 32 || samplesPerPixel != 1 || sampleFormat != 3)
            {
                Debug.LogError("仅支持单通道Float32类型的GeoTIFF");
                return;
            }

            // 读取第一条带(非分块场景下,整幅图可能仅一个条带)
            int stripByteSize = width * 4 * rowsPerStrip;
            byte[] stripBytes = new byte[stripByteSize];
            tiff.ReadEncodedStrip(0, stripBytes, 0, stripByteSize);

            // 字节数组转Float32数组
            float[] elevationData = new float[width * rowsPerStrip];
            Buffer.BlockCopy(stripBytes, 0, elevationData, 0, stripByteSize);

            // 获取(0,0)位置的高程值
            float elevation = elevationData[0];
            Debug.Log($"坐标(0,0)的高程值:{elevation:F2}m");

            // 读取任意(row, col)位置的高程值
            // int targetRow = 1;
            // int targetCol = 1;
            // int pixelIndex = targetRow * width + targetCol;
            // float targetElevation = elevationData[pixelIndex];
        }
    }
}

关键说明

  • 格式验证:通过SAMPLEFORMAT=3确认是浮点型,BITSPERSAMPLE=32对应float32,SAMPLESPERPIXEL=1确认是单通道灰度图
  • 非分块TIFF用条带(Strip)存储,通过ReadEncodedStrip直接读取字节数据
  • 利用Buffer.BlockCopy直接完成字节到float的转换,无需额外解码(匹配原生存储格式)
  • 像素索引计算规则:行号 * 图像宽度 + 列号

内容的提问来源于stack exchange,提问作者PengWin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:33:14