GlobalKey imgkey = GlobalKey()
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');
});
});
}