【问题标题】:How to read GPS Coordinates from JPG EXIF using CCR.EXIF in Delphi?如何在 Delphi 中使用 CCR.EXIF 从 JPG EXIF 读取 GPS 坐标?
【发布时间】:2016-04-03 09:57:39
【问题描述】:

使用 GPSLatitude 和 GPSLatitude 属性的 Assign 方法设置 GPS 坐标非常简单,但是读取坐标让我很困惑。我正在尝试访问 TGPSLongitude 类,但没有任何属性或方法可以为我呈现坐标的真实/浮动甚至 DMS。

示例图片:http://www.cde.co.za/share/IMG_5889.JPG

我当前没有编译的代码:

imgJpg: TJpegImageEx;
GPS_D: Real;

try
  imgJpg.LoadFromFile(FolderName+'\'+SR.Name);
  GPS_D:= imgJpg.ExifData.GPSLatitude.Degrees;
except
  GPS_D:= 0;
end;

编译器在我尝试分配 GPS_D 时停止,出现错误“[DCC Error] Main.pas(205): E2010 Incompatible types: 'Real' and 'TTiffLongWordFraction'” 这显然是因为我无法分配度属性为真。问题是如何从 TGPSLongitude 中提取度数或十进制值?

【问题讨论】:

  • 我当前的代码没有编译什么编译器错误,在哪一行?还有,TdmSH是什么以及它的方法DMStoDec
  • @TomBrunberg DMStoDec 采用 3 个实数值并将其转换为 GPS 十进制。但是我已经简化了源示例。编译器停在我尝试分配 GPS_D 并出现错误“[DCC Error] Main.pas(205): E2010 Incompatible types: 'Real' and 'TTiffLongWordFraction'” 这显然是因为我无法将 Degrees 属性分配给一个真实的。问题是如何从 TGPSLongitude 提取度数或十进制值?感谢您的宝贵时间。

标签: delphi gps


【解决方案1】:

将 GPS 信息提取为string 的简单方法:

var myLat, myLong : string;
...
myLat := myJpeg.ExifData.GPSLatitude.AsString ; 
myLong := myJpeg.ExifData.GPSLongitude.AsString ;

【讨论】:

    【解决方案2】:

    深入查看源代码,似乎可以使用“商”属性。开发人员没有存储小数浮点数,而是选择存储组件 Numerator、Denominator 和 Quotient。

    我不认为这就是它的用途,但它确实有效!感谢大家的时间。

    因此,要使用 CCR.EXIF 从 JPG 文件中读取 GPS 坐标,我执行以下操作:

    var
        imgJpg: TJpegImageEx;
        d,m,s,lat: real;
    
    imgJpg.LoadFromFile(FolderName+'\'+SR.Name); {Load the particular JPG File }
    d:= imgJpg.ExifData.GPSLatitude.Degrees.Quotient; {Degrees}
    m:= imgJpg.ExifData.GPSLatitude.Minutes.Quotient; {Minutes}
    s:= imgJpg.ExifData.GPSLatitude.Seconds.Quotient; {Seconds}
    
    {Now determine the sign}
    if imgJpg.ExifData.GPSLatitude.Direction=ltNorth then
      ref:= 1
    else
      ref:= -1;
    
    {Convert to decimal}
    lat:= ref*(d+(m/60)+(s/60/60));
    

    lat 现在包含纬度。当然也可以长期这样做。

    【讨论】:

    • 有人能告诉我如何在 Lazarus 中找到确切的东西吗?
    • Hein,您的解决方案对我帮助很大。我想补充一点,CCRexif 在许多情况下都不能可靠地工作。在我的小米米 8 的 JPG 中,它为 GPSLatitudeRef、GPSLatitude.Direction、GPSLatitude.MissingOrInvalid 等提供了错误(无效)值。在这里,您可以求助于 GPSLatitude.ToString,它在最后一个字符中包含方向('N' 或 'S')。当没有 GPS 标签时,它也会是 '0,0,0,N',这显然比 MissingOrInvalid 更可靠。
    • 更正:事实上,当没有 GPS 标签时,它会是 '0,0,0N'。
    【解决方案3】:

    来自 CCRExif 1.5.1 中现有的文档 -

    全球定位系统

    Exif 标准允许设置 GPS(即定位)数据, 它存储在自己的部分/子 IFD 中。使用 TExifData,您可以 读写这个,标准的 GPS 标签集被暴露 作为该类的属性。然而,需要注意的重要一点是 GPS坐标可以用两种不同的方式表示, 单个十进制值或以度、分和秒表示。 Exif 使用第二种形式,因此如果您希望将 GPS 坐标分配给 一个图像,你所拥有的只是所需的值,表示为 小数,你需要先转换成另一种形式。 (对于‘一 关闭”转换,您可以使用以下网站: http://www.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html.) 一旦你 但是,具有所需形式的坐标,将它们分配给 图像是这样的:

    with TExifData.Create do 
    try
      LoadFromGraphic(ImageFile); 
      GPSLatitude.Assign(51, 25, 32.1, ltNorth);
      GPSLongitude.Assign(0, 12, 29.2, lnEast); 
      SaveToGraphic(ImageFile);
    finally 
     Free; 
    end;
    

    查看源代码内部倾向于:

    TGPSLatitude = class(TGPSCoordinate)
    

    TGPSCoordinate类的声明在公共部分

    property Degrees: TExifFraction index 0 read GetValue;
    property Minutes: TExifFraction index 1 read GetValue;
    property Seconds: TExifFraction index 2 read GetValue;
    property Direction: AnsiChar read GetDirectionChar write SetDirectionChar;
    

    此外,zip 文件中还有几个演示应用程序。

    LE:看完cmets后,我又看了一下demo,在ExifListdemo中ExifListFrame.pas中有如下代码: p>

     procedure AddValue(const Name: string; Coord: TGPSCoordinate); overload;
      var
        DirectionStr: string;
      {$IFDEF BUGGYCOMPILER}
        Degrees, Minutes, Seconds: TExifFraction; //work around D2006 compiler bug with intermediate vars
      {$ENDIF}
      begin
        if Coord.MissingOrInvalid then Exit;
        case Coord.Direction of
          'N': DirectionStr := 'north';
          'S': DirectionStr := 'south';
          'W': DirectionStr := 'west';
          'E': DirectionStr := 'east';
        else DirectionStr := '';
        end;
      {$IFDEF BUGGYCOMPILER}
        Degrees := Coord.Degrees;
        Minutes := Coord.Minutes;
        Seconds := Coord.Seconds;
        AddValue(Name, '%g°, %g minutes and %g seconds %s', [Degrees.Quotient,
          Minutes.Quotient, Seconds.Quotient, DirectionStr]);
      {$ELSE}
        AddValue(Name, '%g°, %g minutes and %g seconds %s', [Coord.Degrees.Quotient,
          Coord.Minutes.Quotient, Coord.Seconds.Quotient, DirectionStr]);
      {$ENDIF}
      end;
    

    【讨论】:

    • 我手头没有Delphi安装,所以无法提供该类的完整使用示例。
    • 谢谢,我已经彻底阅读了文档,您的摘录显示了如何分配 TGPSCoordinate 实例,即编写它。我有一个带有地理标记的现有 JPG,我需要它的坐标。 Degrees, minutes, seconds 属性是 TExifFraction 类型,一个包含组件的打包记录,不清楚如何获取实际值。请参阅我在上面添加的源代码中的尝试。
    猜你喜欢
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2021-05-19
    • 2022-08-22
    • 2012-06-18
    相关资源
    最近更新 更多