【Flutter 问题系列第 22 篇】在 Flutter 中如何截取屏幕并显示到页面中,以及如何将截图保存到相册

您所在的位置:网站首页 苹果电脑截图怎么保存到相册 【Flutter 问题系列第 22 篇】在 Flutter 中如何截取屏幕并显示到页面中,以及如何将截图保存到相册

【Flutter 问题系列第 22 篇】在 Flutter 中如何截取屏幕并显示到页面中,以及如何将截图保存到相册

2024-06-19 06:31| 来源: 网络整理| 查看: 265

这是【Flutter 问题系列第 22 篇】,如果觉得有用的话,欢迎关注专栏。

关于在 Flutter 中如何截取屏幕,以及如何将截图保存到相册的文章少之又少,即使有,也是错误一大片,有的甚至运行后都报错,就这都直接发出来了,真是可恶啊!

所以我整理了这篇博客,实现了两个功能

如何截取整个屏幕或屏幕中的某一部分,并显示到页面中如何将截取的图片,保存到相册中

这两个功能都已亲测并无问题,源码会全部奉上,如果有用,希望可以给个三连,接下来是博客正文。

文章目录 一:如何截取屏幕,并显示到页面中1:RepaintBoundary 组件介绍2:如何截图3:如何在页面中显示截图 二:如何将截取到的图片,保存到相册中1:配置权限、引用插件2:存储图片到相册

一:如何截取屏幕,并显示到页面中

依照国际惯例,先上效果图(没有先看到效果图,估计你们都会走吧~)

由效果图可以看出来,截取到的每一帧都是不同的图片,功能实现了,接下来就是如何实现功能的代码了。 1:RepaintBoundary 组件介绍

我们知道在 Flutter 中万物皆组件,所以接下来要说的截图其实也是一个组件,与其说是截取屏幕,不如说是截取组件。

而这个组件的名称就是 RepaintBoundary ,源码如下所示

RepaintBoundary({ Key key, Widget child })

使用起来也很简单,直接套在你想要截的组件上面就行了,如果你要截取的是整个页面,套在 Scaffold 外面即可。

因为 RepaintBoundary 继承自 SingleChildRenderObjectWidget 而我们又需要获取到被截取组件的状态,所以第一个参数 Key 的类型应为 GlobalKey,如下所示

GlobalKey _repaintKey = GlobalKey(); // 可以获取到被截图组件状态的 GlobalKey

而第二个参数就是你需要截取的组件,如下代码所示

RepaintBoundary( key: _repaintKey, child: Image.asset("assets/girl.gif", width: 200, height: 200, fit: BoxFit.cover), ) 2:如何截图

接下来要说的是最核心的部分了,就是如何获取到截取图片的数据。

这里我直接把代码复制到下方了,关键代码都有解释,相信大家一看就懂了。

/// 获取截取图片的数据 Future _getImageData() async { BuildContext buildContext = _repaintKey.currentContext; if (buildContext != null) { RenderRepaintBoundary boundary = buildContext.findRenderObject(); // 第一次执行时,boundary.debugNeedsPaint 为 true,此时无法截图(如果为true时直接截图会报错) if (boundary.debugNeedsPaint) { // 延时一定时间后,boundary.debugNeedsPaint 会变为 false,然后可以正常执行截图的功能 await Future.delayed(Duration(milliseconds: 20)); // 重新调用方法 return _getImageData(); } // 获取当前设备的像素比 double dpr = ui.window.devicePixelRatio; // pixelRatio 代表截屏之后的模糊程度,因为不同设备的像素比不同 // 定义一个固定数值显然不是最佳方案,所以以当前设备的像素为目标值 ui.Image image = await boundary.toImage(pixelRatio: dpr); ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png); Uint8List imageBytes = byteData.buffer.asUint8List(); // 返回图片的数据 return imageBytes; } }

这里将图片数据以 Uint8List 的格式返回,方便后面显示图片。

3:如何在页面中显示截图

我们可以通过 Image.memory(); 方法从内存中加载图片,而该方法需要传入图片的数据,数据类型是 Uint8List ,这也是为什么要把图片数据以 Uint8List 类型返回了。

如果要显示的截图有多张,则定义一个列表

List _images = []; // 存放所有截图的列表

然后当点击底部按钮时,执行如下函数

/// 执行截图并显示到页面中 void _doScreenShots() async { Uint8List data = await _getImageData(); _images.add(data); setState(() {}); }

最后就是遍历这个列表,把图片显示出来就行了,如下代码所示

GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, ), itemCount: _images.length, itemBuilder: (BuildContext context, int index) { if (_images.isEmpty) { return Container(); } return Image.memory(_images[index], fit: BoxFit.cover); }, )

至此,如何截取屏幕,并显示到页面中便介绍完毕了,一定要注意的是,当 _getImageData() 方法中的 boundary.debugNeedsPaint 为 true 时,一定不要去截图,一定不要去截图,一定不要去截图,否则会报

‘!debugNeedsPaint’:is not true 的错误,切记!!!

二:如何将截取到的图片,保存到相册中

如何截图已经说过了,如何将截图保存到相册中呢?

1:配置权限、引用插件

保存到相册的话就要涉及到存储文件的权限,以及如何把图片保存到相册的问题了。

这里引用两个插件

权限控制插件 permission_handler图片存储到相册插件 image_gallery_saver

然后在 pubspec.yaml 文件中引入这两个插件,如下所示

dependencies: permission_handler: ^8.1.1 # 权限控制插件 by Allen Su image_gallery_saver: ^1.6.9 # 图片存储到相册插件 by Allen Su

安卓系统,需要在 android/app/src/main/AndroidManifest.xml 文件中添加如下代码

苹果系统,需要在 ios/Runner/Info.plist 文件中添加如下代码

NSPhotoLibraryAddUsageDescription 请允许APP保存图片到相册

(因博主是从事安卓开发的,关于 ios 这里是翻阅的资料,并没有证实,应该没有什么问题)

2:存储图片到相册

权限问题解决了,接下来就是如何把截图存储到本地相册了,很简单,其实一行代码就可以了,下面的代码包含获取存储权限和存储图片到相册,如下所示

/// 执行存储图片到本地相册 void _doSaveImage() async { // 如果用户已授权存储权限 if (await Permission.storage.request().isGranted) { Uint8List data = await _getImageData(); await ImageGallerySaver.saveImage(data); } else { // 没有存储权限时,弹出没有存储权限的弹窗 } }

当点击按钮时,是获取权限,如下图所示

点击允许后,图片会自动保存到相册,如下图所示

可以看到,这是已经保存到相册后的视图了,至此,关于在 Flutter 中如何截取屏幕并显示到页面中,以及如何将截图保存到相册便介绍完毕了,按照我写的一步一步来,应该不会有什么问题。

你的问题得到解决了吗?欢迎在评论区留言。

赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。

结束语 Google 的 Flutter 越来越火,截止 2021年6月3日 GitHub 标星已达 123K,Flutter 毅然是一种趋势,所以作为前端开发者,没有理由不趁早去学习。 无论你是 Flutter 新手还是已经入门了,不妨先点个关注,后续我会将 Flutter 中的常用组件(含有源码分析、组件的用法及注意事项)以及可能遇到的问题写到 CSDN 博客中,希望自己学习的同时,也可以帮助更多的人。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3