Flutter生成长截图并保存在本地

xml中需要配置权限

   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!--写入外部存储权限-->
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <!--读取外部存储权限-->

yaml文件需要引入

  permission_handler: ^8.1.1 # 权限控制插件 by Allen Su
  image_gallery_saver: ^1.6.9 # 图片存储到相册插件 by Allen Su
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';

class ScreenShotPage extends StatefulWidget {
  @override
  _ScreenShotPageState createState() => _ScreenShotPageState();
}

class _ScreenShotPageState extends State<ScreenShotPage> {
  GlobalKey _repaintKey = GlobalKey(); // 可以获取到被截图组件状态的 GlobalKey
  List<Uint8List> _images = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        padding: EdgeInsets.only(right: 10),
        child: RepaintBoundary(
            //而第二个参数就是你需要截取的组件,如下代码所示
            key: _repaintKey,
            child: Column(
              children: [
                Container(
                  width: double.infinity,
                  color: Color(0xffe8eaed),
                  child: Column(
                      children: <Widget>[Column(children: _listWidget())]),
                ),
                Container(
                  height: 200,
                ),
                InkWell(
                  onTap: () async {
                    _getImageData();
                    Uint8List data = await _getImageData();
                    _images.add(data);
                    _doSaveImage();
                    print("---------------");
                    print(_images[0]);
                  },
                  child: Text("22222222"),
                ),
              ],
            )),
      )),
    );
  }

  ///数组
  List<Widget> _listWidget() {
    List<Widget> _list = List();
    for (int index = 0; index < 40; index++) {
      _list
          .add(Container(height: 30, child: Center(child: Text('屏幕截图$index'))));
    }
    return _list;
  }

  /// 获取截取图片的数据
  Future<Uint8List> _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;
    }
  }

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

  }

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

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可可鸭~

想吃糖~我会甜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值