如何在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
相关产品推荐
相关产品推荐

