You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:17:23