flutter将图片保存到应用沙盒目录中

需求是:去中心化APP实现用户头像修改功能。

一共想到了三种方式:

1、将图片的path存在shared_preferences

缺点:实际保存的是图片在设备中的地址,一旦用户将图片删除,该地址就无法读取出图片,那么头像就无法显示了

2、将图片转成base64编码字符串,存在shared_preferences中

实现代码:

import 'dart:convert';
import 'dart:io';
import 'package:shared_preferences/shared_preferences.dart';


1. 将图片转换为 Base64 编码的字符串
Future<String> encodeImageToBase64(File image) async {
  final bytes = await image.readAsBytes();
  return base64Encode(bytes);
}

2. 将 Base64 编码的字符串存储到 SharedPreferences 中
Future<void> saveImageToSharedPreferences(String key, File image) async {
  // 将图片转换为 Base64 编码的字符串
  final base64String = await encodeImageToBase64(image);
  
  // 获取 SharedPreferences 实例
  final prefs = await SharedPreferences.getInstance();
  
  // 存储 Base64 编码字符串
  await prefs.setString(key, base64String);
}

3. 从 SharedPreferences 中读取和解码图片
final prefs = await SharedPreferences.getInstance();
final storedBase64String = prefs.getString('image_base64');

 if (storedBase64String != null) {
      setState(() {
        base64String = storedBase64String;
        imageBytes = base64Decode(storedBase64String);
      });
    }

Widget build(BuildContext context) {
    return Center(
      child: imageBytes == null
          ? CircularProgressIndicator() // 显示加载指示器直到图片加载完成
          : Image.memory(imageBytes!), // 使用 Image.memory 显示图片
    );
  }

缺点:base64字符串解码成图片的时间太长,UI切换时头像会闪烁,使用感差

3、将图片存在应用的沙盒目录中,再将图片路径存在shared_preferences中,一般用户不会访问更不会删除沙盒目录中的文件,所以相对来说是最优解。

实现代码:

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';


File? avatar = null;


/**从设备中选取图片*/
    final ImagePicker picker = ImagePicker();
    final XFile? image = await picker.pickImage( source: ImageSource.camera);//相机拍照

    if (image == null)
        return; // 处理用户取消拍照的情况
    setState(() {
        avatar = File(image.path);
    });



/**点击‘保存’按钮*/
TextButton(
    onPressed: () async {
    print("确认修改");

    var _avatar = await saveImageToCustomDirectory(avatar);
    if (_avatar == 'error') {
        showToast('保存失败');
        return;
    }
    
    //保存图片地址
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('avatar', !_avatar );
    }
    child:Text('保存修改');
)

//将图片存入沙盒目录,返回图片地址
  Future<String> saveImageToCustomDirectory(File? image) async {
    if (image == null) {
      return '';
    }
    try {
      deleteImageFromDirectory(Global.userNewWallet.avatar);
      // 获取应用的沙盒目录
      final directory = await getApplicationDocumentsDirectory();
      // 自定义创建名为 'images' 的目录
      final customDir = Directory('${directory.path}/images');

      // 检查目录是否存在,存在就跳过创建
      if (!customDir.existsSync()) {
        await customDir.create(recursive: true);
      }

      // 保存图片到该目录
      final imagePath = '${customDir.path}/${basename(image.path)}';
      await image.copy(imagePath); // 使用 copy 方法将文件复制到目标位置
      return imagePath; // 返回图片路径
    } catch (e) {
      print(e);

      return 'error';
    }
  }

//将图片从沙盒目录删除
  Future<void> deleteImageFromDirectory(String? imagePath) async {
    if (imagePath == null) {
      return;
    }
    final file = File(imagePath);
    // 检查文件是否存在
    if (await file.exists()) {
      try {
        await file.delete();
        print('Image deleted successfully.');
      } catch (e) {
        print('Error deleting image: $e');
      }
    } else {
      print('Image file does not exist.');
    }
  }

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Flutter图片保存到本地并分享到QQ,你可以按照以下步骤操作: 1. 将图片保存到本地储,可以使用以下代码: ```dart import 'dart:io'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; Future<void> saveImageToGallery(BuildContext context, String imageUrl) async { try { // 获取应用程序目录 Directory appDocDir = await getApplicationDocumentsDirectory(); // 获取文件名 String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1); // 组合路径 String filePath = "${appDocDir.path}/$fileName"; // 下载图片 HttpClient httpClient = HttpClient(); HttpClientRequest request = await httpClient.getUrl(Uri.parse(imageUrl)); HttpClientResponse response = await request.close(); Uint8List bytes = await consolidateHttpClientResponseBytes(response); // 保存图片到本地 File file = File(filePath); await file.writeAsBytes(bytes); // 保存图片到相册 await ImageGallerySaver.saveImage(bytes); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("图片保存到相册"), )); } catch (e) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("保存图片失败: $e"), )); } } ``` 2. 调用QQ分享功能,可以使用以下代码: ```dart import 'package:flutter/material.dart'; import 'package:flutter_qq_share/flutter_qq_share.dart'; Future<void> shareImageToQQ(BuildContext context, String imageUrl) async { try { // 获取应用程序目录 Directory appDocDir = await getApplicationDocumentsDirectory(); // 获取文件名 String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1); // 组合路径 String filePath = "${appDocDir.path}/$fileName"; // 下载图片 HttpClient httpClient = HttpClient(); HttpClientRequest request = await httpClient.getUrl(Uri.parse(imageUrl)); HttpClientResponse response = await request.close(); Uint8List bytes = await consolidateHttpClientResponseBytes(response); // 保存图片到本地 File file = File(filePath); await file.writeAsBytes(bytes); // 分享图片到QQ await FlutterQQShare.shareImageToQQ(filePath); } catch (e) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("分享图片失败: $e"), )); } } ``` 调用 `saveImageToGallery` 函数可以将图片保存到本地并保存到相册,调用 `shareImageToQQ` 函数可以将图片分享到QQ。你可以根据自己的需求修改和调整这些代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值