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

如何在Flutter应用中实现相机拍照时为图片添加地理标签位置水印

拍照添加位置水印功能实现方案

1. 新增依赖

首先在pubspec.yaml的dependencies节点下添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^any # 保留你现有的版本即可
  location: ^5.0.0 # 用于获取设备位置信息
  geocoding: ^2.1.0 # 用于将经纬度转换为可读的地址文本
  image: ^4.0.17 # 用于图片编辑、添加文字水印
  path_provider: ^2.1.0 # 用于存储处理后的带水印图片

执行flutter pub get完成依赖安装。

2. 配置权限

Android端

在android/app/src/main/AndroidManifest.xml的manifest节点下添加权限声明:

<!-- 位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 相机、存储权限如果之前没配置,也需要补上 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

iOS端

在ios/Runner/Info.plist的dict节点下添加权限描述:

<!-- 位置权限描述 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要获取位置信息用于添加照片水印</string>
<!-- 相机权限如果之前没配置,也需要补上 -->
<key>NSCameraUsageDescription</key>
<string>需要使用相机拍摄照片</string>

3. 修改核心拍照逻辑

替换你原来的pickImage方法,修改后代码如下:

import 'package:image/image.dart' as img; // 导入图片处理包,加别名避免和系统类冲突
import 'package:location/location.dart';
import 'package:geocoding/geocoding.dart' as geo;
import 'package:path_provider/path_provider.dart';

Future pickImage(ImageSource source) async {
  try {
    // 1. 检查并请求位置权限
    Location location = Location();
    bool serviceEnabled;
    PermissionStatus permissionGranted;
    LocationData locationData;

    serviceEnabled = await location.serviceEnabled();
    if (!serviceEnabled) {
      serviceEnabled = await location.requestService();
      if (!serviceEnabled) return;
    }

    permissionGranted = await location.hasPermission();
    if (permissionGranted == PermissionStatus.denied) {
      permissionGranted = await location.requestPermission();
      if (permissionGranted != PermissionStatus.granted) return;
    }

    // 2. 获取当前位置,转换为可读地址
    locationData = await location.getLocation();
    List<geo.Placemark> placemarks = await geo.placemarkFromCoordinates(
        locationData.latitude!, locationData.longitude!);
    geo.Placemark place = placemarks.first;
    String locationText = "${place.locality} ${place.subLocality} ${place.street}";

    // 3. 拍摄获取原图
    final image = await ImagePicker.pickImage(source: source);
    if(image == null) return;

    // 4. 给图片添加位置水印
    final originalImageFile = File(image.path);
    final originalImageBytes = await originalImageFile.readAsBytes();
    img.Image? originalImage = img.decodeImage(originalImageBytes);
    if (originalImage == null) return;

    // 在图片左下角绘制位置文字,可自行调整字体大小、颜色、坐标位置
    img.drawString(originalImage, img.arial_24, 20, originalImage.height - 60, 
        locationText, color: img.getColor(255, 255, 255));

    // 5. 保存处理后的带水印图片到本地
    final tempDir = await getTemporaryDirectory();
    final processedImagePath = '${tempDir.path}/watermarked_${DateTime.now().millisecondsSinceEpoch}.jpg';
    final processedImageFile = File(processedImagePath);
    await processedImageFile.writeAsBytes(img.encodeJpg(originalImage));

    // 6. 更新状态显示带水印的图片
    setState(() => this.image = processedImageFile);

  } on PlatformException catch(e) {
    print('操作失败:${e.message}');
  } catch (e) {
    print('未知错误:$e');
  }
}

4. 布局代码调整

你现有的布局代码无需修改,已经可以正常显示处理后的带水印图片。如果需要调整水印的字体、颜色、显示位置,修改drawString方法的对应参数即可。

内容的提问来源于stack exchange,提问作者Nero Chaniago

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:36:03