如何在Xamarin Forms中为拍摄的照片添加经纬度信息?
为Xamarin.Forms相机照片添加经纬度EXIF信息
嘿,我来帮你搞定这个问题!要给拍的照片加上经纬度属性,咱们得完成两个核心步骤:获取当前设备的地理位置,以及把经纬度写入照片的EXIF元数据。下面是具体的实现方案,一步步来就行:
1. 先装必要的依赖库
首先得确保你装了两个NuGet包:
Xamarin.Essentials:用来获取设备的地理位置ExifLib.PCL:用来修改照片的EXIF信息
直接通过NuGet包管理器搜索安装就行,很方便。
2. 写个获取地理位置的方法
咱们需要先拿到当前的经纬度,这里写个异步方法来处理,还顺带做了异常捕获,避免各种权限或设备不支持的问题:
using Xamarin.Essentials; private async Task<Location> GetCurrentLocation() { try { // 中等精度,超时10秒,平衡定位速度和准确性 var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10)); var location = await Geolocation.GetLocationAsync(request); if (location != null) { return location; } } catch (FeatureNotSupportedException) { await DisplayAlert("提示", "你的设备不支持定位功能哦", "确定"); } catch (FeatureNotEnabledException) { await DisplayAlert("提示", "麻烦先开启定位权限哈", "确定"); } catch (PermissionException) { await DisplayAlert("提示", "请授予应用定位权限哦", "确定"); } catch (Exception ex) { await DisplayAlert("错误", $"获取位置失败啦:{ex.Message}", "确定"); } return null; }
3. 修改拍照方法,加入经纬度写入逻辑
接下来把你的TakePhoto_Clicked方法改一改,拍完照后获取位置,再把经纬度写入照片的EXIF里:
private MediaFile _mediaFile; private async void TakePhoto_Clicked(object sender, EventArgs e) { await CrossMedia.Current.Initialize(); if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported) { await DisplayAlert("No Camera", ":( No camera available.", "OK"); return; } _mediaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions { Directory = "Sample", Name = "myImage.jpg", SaveToAlbum = true }); if (_mediaFile == null) return; // 先拿到当前位置 var currentLocation = await GetCurrentLocation(); if (currentLocation != null) { // 开始写入EXIF信息 using (var stream = _mediaFile.GetStream()) { // 读取原照片的EXIF数据 var exifReader = new ExifReader(stream); // 创建EXIF写入器,指向照片文件路径 var exifWriter = new ExifWriter(_mediaFile.Path); // 注意:EXIF里的经纬度需要转成度分秒格式,所以咱们用辅助方法转一下 var latDms = ConvertDecimalToDegreesMinutesSeconds(currentLocation.Latitude); var lngDms = ConvertDecimalToDegreesMinutesSeconds(currentLocation.Longitude); // 写入纬度和方向(北纬N/南纬S) exifWriter.SetTagValue(ExifTags.GPSLatitude, latDms); exifWriter.SetTagValue(ExifTags.GPSLatitudeRef, currentLocation.Latitude >= 0 ? "N" : "S"); // 写入经度和方向(东经E/西经W) exifWriter.SetTagValue(ExifTags.GPSLongitude, lngDms); exifWriter.SetTagValue(ExifTags.GPSLongitudeRef, currentLocation.Longitude >= 0 ? "E" : "W"); // 保存修改后的EXIF exifWriter.Save(); } } LocalPathLabel.Text = _mediaFile.Path; FileImage.Source = ImageSource.FromStream(() => { return _mediaFile.GetStream(); }); } // 辅助方法:把十进制的经纬度转成EXIF需要的度分秒格式 private Tuple<double, double, double> ConvertDecimalToDegreesMinutesSeconds(double coordinate) { var absoluteCoordinate = Math.Abs(coordinate); var degrees = Math.Floor(absoluteCoordinate); var minutes = Math.Floor((absoluteCoordinate - degrees) * 60); var seconds = (absoluteCoordinate - degrees - minutes / 60) * 3600; return Tuple.Create(degrees, minutes, seconds); }
4. 别忘了配置平台权限!
这个很重要,不然定位功能会用不了:
- Android:打开
AndroidManifest.xml,添加下面的权限:<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.location.gps" /> - iOS:打开
Info.plist,添加定位权限的描述:<key>NSLocationWhenInUseUsageDescription</key> <string>需要获取您的位置信息,为拍摄的照片添加地理位置标签</string>
一些小提示
- 测试的时候要确保设备的定位已经打开,并且给应用授予了定位权限;
- 有些相册应用可能不会立刻刷新显示新的EXIF信息,你可以把照片导到电脑上用看图工具查看(比如Windows的照片应用,右键属性里看详细信息);
- 如果
ExifLib.PCL用着不顺手,也可以试试MetadataExtractor这个库,功能更全一点。
内容的提问来源于stack exchange,提问作者Suraj
相关产品推荐
相关产品推荐

