参考自:flutter 截图和保存图片到本地和相册,并做分享
第一步:注册全局的key与RepaintBoundary匹配,来标明截图内容。
//全局key-截图key
final GlobalKey repaintWidgetKey = GlobalKey();
第二步:将需要截图的widget包裹在RepaintBoundary组件中,加入key属性。
RepaintBoundary(
key: repaintWidgetKey,
child: Container(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: WebViewWidget(
controller: WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadHtmlString(HtmlUtils.getHtmlData(newDetailsEntity.content.toString(), 14))),
),
SizedBox(
height: 50,
child: Row(
children: [
Expanded(
child: InkWell(
onTap: (){
RepaintBoundaryUtils().savePhoto(repaintWidgetKey);
},
child: RichText(
textAlign: TextAlign.center,
text:const TextSpan(
children: [
TextSpan(
text: "保存 ",
style: TextStyle(fontSize: 14,color: Colors.black)
),
WidgetSpan(child: LoadAssetImage("home/img_zhuanfa",width: 18,height: 18)),
]
),
),
)
)
],
),
)
],
),
),
)
第三步:调用保存封装类方法
RepaintBoundaryUtils().savePhoto(repaintWidgetKey);
第四步:封装类代码
import 'dart:io';
import 'dart:typed_data';
import 'dart:async';
import 'dart:ui';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:oktoast/oktoast.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
//全局key-截图key
late GlobalKey boundaryKey;
class RepaintBoundaryUtils {
//生成截图
/// 截屏图片生成图片流ByteData
Future<String> captureImage() async {
RenderRepaintBoundary? boundary = boundaryKey.currentContext!
.findRenderObject() as RenderRepaintBoundary?;
double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比
var image = await boundary!.toImage(pixelRatio: dpr);
// 将image转化成byte
ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
var filePath = "";
Uint8List pngBytes = byteData!.buffer.asUint8List();
// 获取手机存储(getTemporaryDirectory临时存储路径)
Directory applicationDir = await getTemporaryDirectory();
// getApplicationDocumentsDirectory();
// 判断路径是否存在
bool isDirExist = await Directory(applicationDir.path).exists();
if (!isDirExist) Directory(applicationDir.path).create();
// 直接保存,返回的就是保存后的文件
File saveFile = await File(
"${applicationDir.path}${DateTime.now().toIso8601String()}.jpg")
.writeAsBytes(pngBytes);
filePath = saveFile.path;
// if (Platform.isAndroid) {
// // 如果是Android 的话,直接使用image_gallery_saver就可以了
// // 图片byte数据转化unit8
// Uint8List images = byteData!.buffer.asUint8List();
// // 调用image_gallery_saver的saveImages方法,返回值就是图片保存后的路径
// String result = await ImageGallerySaver.saveImage(images);
// // 需要去除掉file://开头。生成要使用的file
// File saveFile = new File(result.replaceAll("file://", ""));
// filePath = saveFile.path;
//
//
// } else if (Platform.isIOS) {
// // 图片byte数据转化unit8
//
// }
return filePath;
}
//申请存本地相册权限
Future<bool> getPormiation() async {
if (Platform.isIOS) {
var status = await Permission.photos.status;
if (status.isDenied) {
Map<Permission, PermissionStatus> statuses = await [
Permission.photos,
].request();
// saveImage(globalKey);
}
return status.isGranted;
} else {
var status = await Permission.storage.status;
if (status.isDenied) {
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
].request();
}
return status.isGranted;
}
}
//保存到相册
void savePhoto(GlobalKey repaintWidgetKey) async {
boundaryKey=repaintWidgetKey;
RenderRepaintBoundary? boundary = boundaryKey.currentContext!
.findRenderObject() as RenderRepaintBoundary?;
double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比
var image = await boundary!.toImage(pixelRatio: dpr);
// 将image转化成byte
ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
//获取保存相册权限,如果没有,则申请改权限
bool permition = await getPormiation();
var status = await Permission.photos.status;
if (permition) {
if (Platform.isIOS) {
if (status.isGranted) {
Uint8List images = byteData!.buffer.asUint8List();
final result = await ImageGallerySaver.saveImage(images,
quality: 60, name: "hello");
showToast("保存成功");
}
if (status.isDenied) {
print("IOS拒绝");
}
} else {
//安卓
if (status.isGranted) {
print("Android已授权");
Uint8List images = byteData!.buffer.asUint8List();
final result = await ImageGallerySaver.saveImage(images, quality: 60);
if (result != null) {
showToast("保存成功");
} else {
print('error');
// toast("保存失败");
}
}
}
}else{
//重新请求--第一次请求权限时,保存方法不会走,需要重新调一次
savePhoto(boundaryKey);
}
}
}
说明:以下是用到的插件
#保存图片到相册
image_gallery_saver: ^2.0.3
#权限管理
permission_handler: ^8.1.6
#获取临时路径
path_provider: ^2.1.1