flutter 保存图片

叶英哲
2023-12-01

保存本地图片或生成的图片(例如生成的二维码)

1、通过GlobalKey获取currentContext
GlobalKey imgkey = GlobalKey()
2、

1)Widget RepaintBoundary的currentContext上有个findRenderObject方法
2)返回后再去调用toImage创建Image,
3)再通过Image转成ByteData,
4)ByteData再转buffer,
5)获取当前路径
6)创建和写入File
7)GallerySaver包去保存图片
web端需要特殊处理:
1)ByteData转base64后
2)用universal_html包创建a标签模拟点击事件去下载

import 'dart:convert';
import "package:universal_html/html.dart" as html;

static saveWebImg(byteData, fileName) {
    final base64data = base64Encode(byteData);
    final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
    a.download = '${fileName ?? 'download'}.png';
    a.click();
    a.remove();
    EasyLoading.dismiss();
    $tips('保存成功');
  }
RepaintBoundary(
      key: imgkey ,
      child: Image,
    )
import 'package:flutter/foundation.dart';  // 用kIsWeb判断web端

final boundary = imgkey.currentContext!.findRenderObject() as RenderRepaintBoundary;

final image = await boundary.toImage(pixelRatio: 5.0);
final byteData = await (image.toByteData(format: ImageByteFormat.png));
if (byteData != null) {
 final pngBytes = byteData.buffer.asUint8List();
 if (kIsWeb) {
   return saveWebImg(pngBytes, 'fileName');  // 处理web端图片下载
 }
  final directory = (await getApplicationDocumentsDirectory()).path;
  String path = '$directory/${fileName ?? DateTime.now()}.png';
  final imgFile = File(path);
  imgFile.writeAsBytes(pngBytes);
  bool success = false;
  try {
    success = await GallerySaver.saveImage(imgFile.path)
        .then((_success) => _success ?? false);
  } catch (e) {
    print('err === $e');
  }
  EasyLoading.dismiss();
  if (success) return $tips('${tips ?? '保存成功'}!路径:$path');
}

代码:
需安装三个包
permission_handler // 确认权限
gallery_saver // 保存图片
path_provider // 获取路径
并根据包的说明去配置安卓和ios权限

import 'package:permission_handler/permission_handler.dart';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:path_provider/path_provider.dart';

  static createImg({required key, required child}) {
    return RepaintBoundary(
      key: key,
      child: child,
    );
  }

  static saveImg({required key, fileName, tips}) async {
    _saveImage(isSave) async {
      if (isSave) {
        final boundary =
            key.currentContext!.findRenderObject() as RenderRepaintBoundary;
        // We can increse the size of QR using pixel ratio
        final image = await boundary.toImage(pixelRatio: 5.0);
        final byteData = await (image.toByteData(format: ImageByteFormat.png));
        if (byteData != null) {
          final pngBytes = byteData.buffer.asUint8List();
          // getting directory of our phone
          final directory = (await getApplicationDocumentsDirectory()).path;
          String path = '$directory/${fileName ?? DateTime.now()}.png';
          final imgFile = File(path);
          imgFile.writeAsBytes(pngBytes);
          bool success = false;
          try {
            success = await GallerySaver.saveImage(imgFile.path)
                .then((_success) => _success ?? false);
          } catch (e) {
            print('err === $e');
          }
          if (success) return $tips('${tips ?? '保存成功'}!路径:$path');
        }
      }
      $tips('保存失败!');
    }

    if (kIsWeb) {
      return _saveImage(true);
    }
    Permission.storage.request().then((res) async {
      _saveImage(res.isGranted);
    }, onError: (err) {
      print('err === $err');
      $tips('保存失败!无保存图片权限!');
    });
  }

保存网络图片

gallery_saver // 保存图片

import 'package:gallery_saver/gallery_saver.dart';

void _saveNetworkImage() async {
   String path =
       'https://image.shutterstock.com/image-photo/montreal-canada-july-11-2019-600w-1450023539.jpg';
   GallerySaver.saveImage(path).then((bool success) {
     setState(() {
       print('Image is saved');
     });
   });
 }
 类似资料: