是否可以从图像中获取图像 GPS 位置坐标?

Is possible to get Image GPS location coordinates from the Image?

我正在构建一个 Flutter 应用程序,用户可以在其中 post 一张照片及其位置。用户既可以从相机中获取图片,也可以从图库中获取图片。

如果用户用相机拍照,我可以使用设备的 GPS 位置来设置照片的位置。我正在尝试根据图片的元数据获取图片的 GSP 位置,但是,我还没有找到方法。

可以吗?最好的方法是什么?

编辑:我把 "GPS" 放在问题中以使其清楚。我试图找出拍摄照片的物理位置。我还在问题中添加了 "Flutter" 以明确我正面临在 Flutter App 中解决此问题的问题。

如果图像是 JPEG 或 RAW 图像文件,则地理位置元数据将存储为 Exif 标签。在 Android 中,这是通过 ExifInterface class.

完成的

标签是TAG_GPS_LATITUDETAG_GPS_LONGITUDEhttps://developer.android.com/reference/android/media/ExifInterface.html

请注意坐标需要以有理格式表示:度分秒,如dd/1,mm/1,ss/1.

我发现我之前的问题与设备的相机权限有关。通常 android 的相机会访问用户位置并将 GPS 坐标保存为 Exif 标签,但 ios 设备通常不会默认保存此信息,除非用户允许相机应用程序的位置权限。

我更改了我的应用程序以检查图像是否具有 GPS 坐标,并且用户决定是否要共享他的实际位置或图像位置。

我还必须做一些数学运算来处理坐标:

为了使用代码,您必须将包 exif 和 geoflutterfire 添加到您的应用中。

void _checkGPSData() async {
    Map<String, IfdTag> imgTags = await readExifFromBytes( File(image.path).readAsBytesSync() );

    if (imgTags.containsKey('GPS GPSLongitude')) {
      setState(() {
        _imgHasLocation = true;
        _imgLocation = exifGPSToGeoFirePoint(imgTags);
      });
    }

  }


GeoFirePoint exifGPSToGeoFirePoint(Map<String, IfdTag> tags) {

  final latitudeValue = tags['GPS GPSLatitude'].values.map<double>( (item) => (item.numerator.toDouble() / item.denominator.toDouble()) ).toList();
  final latitudeSignal = tags['GPS GPSLatitudeRef'].printable;


  final longitudeValue = tags['GPS GPSLongitude'].values.map<double>( (item) => (item.numerator.toDouble() / item.denominator.toDouble()) ).toList();
  final longitudeSignal = tags['GPS GPSLongitudeRef'].printable;

  double latitude = latitudeValue[0]
    + (latitudeValue[1] / 60)
    + (latitudeValue[2] / 3600);

  double longitude = longitudeValue[0]
    + (longitudeValue[1] / 60)
    + (longitudeValue[2] / 3600);

  if (latitudeSignal == 'S') latitude = -latitude;
  if (longitudeSignal == 'W') longitude = -longitude;

  return  GeoFirePoint(latitude, longitude);
}
exifLatitudeLongitudePoint(var data) async{
if (data.containsKey('GPS GPSLongitude')) {
  final gpsLatitude = data['GPS GPSLatitude'];
  final latitudeSignal = data['GPS GPSLatitudeRef']!.printable;
  List latitudeRation = gpsLatitude!.values.toList();
  List latitudeValue = latitudeRation.map((item) {
    return (item.numerator.toDouble() / item.denominator.toDouble());
  }).toList();
  double latitude = latitudeValue[0] + (latitudeValue[1] / 60) + (latitudeValue[2] / 3600);
  if (latitudeSignal == 'S') latitude = -latitude;
  latValue(latitude);

  final gpsLongitude = data['GPS GPSLongitude'];
  final longitudeSignal = data['GPS GPSLongitude']!.printable;
  List longitudeRation = gpsLongitude!.values.toList();
  List longitudeValue = longitudeRation.map((item) {
    return (item.numerator.toDouble() / item.denominator.toDouble());
  }).toList();
  double longitude =longitudeValue[0] + (longitudeValue[1] / 60) + (longitudeValue[2] / 3600);
  if (longitudeSignal == 'W') longitude = -longitude;
  lngValue(longitude);
}

}