How to read GPS Coordinates from JPG EXIF using CCR.EXIF in Delphi?

风格不统一 提交于 2019-12-02 00:51:53

问题


It's quite easy setting the GPS coordinates using the GPSLatitude and GPSLatitude properties Assign method, but reading the coords has me stumped. I've trying to access the TGPSLongitude class, but none of the properties or methods would render me a real / float or even DMS of the coordinates.

Sample image: http://www.cde.co.za/share/IMG_5889.JPG

My current code that's not compiling:

imgJpg: TJpegImageEx;
GPS_D: Real;

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

The compiler stops at where I try to assign GPS_D with the error "[DCC Error] Main.pas(205): E2010 Incompatible types: 'Real' and 'TTiffLongWordFraction'" This is obviously because I can't assign the Degrees property to a real. The question is how do I extract the degrees or decimal value from TGPSLongitude ?


回答1:


From the documentation existing inside the CCRExif 1.5.1 -

GPS

The Exif standard allows setting GPS (i.e., positioning) data, which is stored in its own section/sub-IFD. Using TExifData, you can both read and write this, the standard set of GPS tags being exposed as properties on that class. An important thing to note, however, is that GPS coordinates can be expressed in two different ways, as either a single decimal value or in terms of degrees, minutes and seconds. Exif uses the second form, so if you wish to assign GPS coordinates to an image, and all you have are the required values expressed as decimals, you’ll need to convert to the other form first. (For ‘one off’ conversions, you can use the following website: http://www.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html.) Once you have coordinates in the required form however, assigning them to an image goes as thus:

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;

Looking inside of the source code lean to:

TGPSLatitude = class(TGPSCoordinate)

and the declaration of the TGPSCoordinate class has in the public section

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;

Also, there are several demo applications inside the zip file.

LE: After reading the comments, I took a look again at the demos, and in the ExifList demo you have in ExifListFrame.pas the following code:

 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;



回答2:


Looking in depth at the source, it seems one can use the "Quotient" property. In stead of storing the decimal float, the developer chose to store the components Numerator, Denominator and Quotient.

I don't think it's how it's meant to be used, but it's working! Thanks for everyone's time.

So, to read the GPS Coordinates from a JPG file using CCR.EXIF, I do the following:

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 now contains the latitude. Same can be done for long of course.




回答3:


Easy way to extract GPS information as a string:

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


来源:https://stackoverflow.com/questions/36383973/how-to-read-gps-coordinates-from-jpg-exif-using-ccr-exif-in-delphi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!