【问题标题】:EXIF PropertyTagGpsLatitude FormatEXIF PropertyTagGpsLatitude 格式
【发布时间】:2018-10-01 17:33:52
【问题描述】:

我正在以编程方式更新一堆扫描的 jpg 图像的 exif 数据

我在更新大多数 exif 数据时没有遇到太多麻烦,但我正在努力设置 gps 坐标

例如我正在尝试将纬度坐标保存如下

PropertyItem PropertyTagGpsLatitude = srcImg.GetPropertyItem(2);
PropertyTagGpsLatitude.Value = System.Text.ASCIIEncoding.ASCII.GetBytes("42/1,5/1,33/1");
srcImg.SetPropertyItem(PropertyTagGpsLatitude);

根据它声明的文档

纬度表示为给出度数的三个有理值, 分,秒。当度、分和秒 表示,格式为dd/1、mm/1、ss/1。当度数和 使用分钟,例如,放弃分钟的分数 保留两位小数,格式为 dd/1, mmmm/100, 0/1。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms534416(v=vs.85).aspx

我可以设置其他与 gps 相关的数据,例如这可以正确翻译

 PropertyItem PropertyTagGpsLatitudeRef = srcImg.GetPropertyItem(1);
 PropertyTagGpsLatitudeRef.Value = System.Text.ASCIIEncoding.ASCII.GetBytes("N");
 srcImg.SetPropertyItem(PropertyTagGpsLatitudeRef);

我没有遇到任何异常,我只是使用 Exif Pilot 实用程序验证 exif 数据,发现它没有正常工作

【问题讨论】:

  • 如果您找到了解决方案;您应该将您的解决方案发布为答案并接受它,而不是将其发布到问题中。这样其他有类似问题的人就会看到这个问题被标记为已解决。

标签: c# image exif


【解决方案1】:

我终于想出了一个可行的解决方案。我加载了一个包含 GPS 信息的现有图像,以检查数据的结构。最后我能想出这个方法在这里

 /// <summary>
 /// Prepares a byte array that hold EXIF latitude/longitude data
 /// </summary>
 /// <param name="degrees">There are 360° of longitude (180° E ↔ 180° W) and 180° of latitude (90° N ↔ 90° S)</param>
 /// <param name="minutes">Each degree can be broken into 60 minutes</param>
 /// <param name="seconds">Each minute can be divided into 60 seconds (”). For finer accuracy, fractions of seconds given by a decimal point are used. Seconds unit multiplied by 100. For example 33.77 seconds is passed as 3377. This gives adequate GPS precision</param>
 /// <returns></returns>
 private static byte[] FloatToExifGps(int degrees, int minutes, int seconds)
 {
      var secBytes = BitConverter.GetBytes(seconds);
      var secDivisor = BitConverter.GetBytes(100);
      byte[] rv = { (byte)degrees, 0, 0, 0, 1, 0, 0, 0, (byte)minutes, 0, 0, 0, 1, 0, 0, 0, secBytes[0], secBytes[1], 0, 0, secDivisor[0], 0, 0, 0 };
      return rv;
 }

并像这样使用它

 PropertyItem PropertyTagGpsLongitude = srcImg.GetPropertyItem(4);
 PropertyTagGpsLongitude.Value = FloatToExifGps(79, 48, 3377);
 srcImg.SetPropertyItem(PropertyTagGpsLongitude);

我希望这对将来的某人有所帮助

【讨论】:

    【解决方案2】:

    我最近遇到了同样的问题,并想分享对我有用的解决方案。 LongitudeDegreeNumerator 等变量具有 uint 类型并提前计算。

    // Longitude: Build a whole property value
    byte[] propertyTagGpsLongitude = new byte[24];
    Buffer.BlockCopy(BitConverter.GetBytes(LongitudeDegreeNumerator), 0, propertyTagGpsLongitude, 0, 4);
    Buffer.BlockCopy(BitConverter.GetBytes(LongitudeDegreeDenominator), 0, propertyTagGpsLongitude, 4, 4);
    Buffer.BlockCopy(BitConverter.GetBytes(LongitudeMinuteNumerator), 0, propertyTagGpsLongitude, 8, 4);
    Buffer.BlockCopy(BitConverter.GetBytes(LongitudeMinuteDenominator), 0, propertyTagGpsLongitude, 12, 4);
    Buffer.BlockCopy(BitConverter.GetBytes(LongitudeSecondNumerator), 0, propertyTagGpsLongitude, 16, 4);
    Buffer.BlockCopy(BitConverter.GetBytes(LongitudeSecondDenominator), 0, propertyTagGpsLongitude, 20, 4);
    

    也许这对某人有用。

    【讨论】:

      猜你喜欢
      • 2014-08-24
      • 2020-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多