美文网首页Flutter
Flutter实现二维码海报图片截取并保存相册

Flutter实现二维码海报图片截取并保存相册

作者: Qson1 | 来源:发表于2020-03-31 12:06 被阅读0次

    截取图片并保存相册

    相信大家见过这种使用场景,就是生成属于自己的二维码海报,可以保存到相册,分享出去。在社交电商类的App中比较常见。
    这种懂原生知道,用原生实现简单,但Flutter中实现这种功能,没接触过的,就会无从下手。下面我们就来通过代码交流下。

    • Demo涉及技术点
      状态管理Provider
      生成二维码
      图片保存

    • Demo涉及的插件

      fluttertoast: 3.1.3 # toast提示框
      provider: ^3.0.0+1 # 状态管理
    
      permission_handler: ^4.3.0 # 权限处理
      image_pickers: ^1.0.7+1 # 图片保存,选取等
      path_provider: ^1.6.1 # 获取文件路径
    
      qr_flutter: ^3.0.1 #二维码
      flutter_swiper: ^1.1.6 # 轮播
    
    • 截取图片代码
      把需要截取的widget,外层包上RepaintBoundary,并设置好key(出现多个key不能重复)
    效果图

    搭建并关联widget截取区域 代码

    _middleWidget(Map data, {double width, double height, int index}) {
        if (data == null || data.length == 0) return Container();
    
        String image = data['path'] ?? '';
        String link = data['page'] ?? '';
        return Container(
          padding: EdgeInsets.all(15.0),
          child: Container(
            child: ClipRRect(
              borderRadius: BorderRadius.circular(10),
              child: RepaintBoundary(
                key: _model.repaintKey[index],
                child: Container(
                  width: width,
                  height: height,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: NetworkImage(image),
                      fit: BoxFit.fill,
                    ),
                  ),
                  child: Stack(
                    alignment: AlignmentDirectional.center,
                    children: <Widget>[
                      Positioned(
                        bottom: size.setWidth(30),
                        child: Center(
                          child: Column(
                            children: <Widget>[
                              ClipRRect(
                                borderRadius:
                                    BorderRadius.circular(size.setSp(20) * 0.5),
                                child: Container(
                                  color: Color(0x88000000),
                                  height: size.setSp(20),
                                  padding: EdgeInsets.symmetric(
                                      horizontal: size.setSp(12)),
                                  child: Center(
                                    child: Text(
                                      '邀请码 ${_model.code}',
                                      style: TextStyle(
                                          fontSize: size.setSp(9),
                                          color: Colors.white),
                                    ),
                                  ),
                                ),
                              ),
                              SizedBox(
                                height: size.setWidth(5),
                              ),
                              QrImage(
                                padding: EdgeInsets.all(size.setWidth(7)),
                                backgroundColor: Colors.white,
                                data: (link != null && link.length > 0)
                                    ? link + "?idCode=${_model.code}"
                                    : '',
                                size: size.setWidth(96),
                              ),
                              SizedBox(
                                height: size.setWidth(15),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    

    UI转成图片

      // 截屏图片生成图片流ByteData
      void saveImage() async {
        // 截屏
        ByteData byteData = await QSCommon.capturePngToByteData(
            _model.repaintKey[_model.currentIndex]);
        // 保存
        File file = await QSCommon.saveImageToCamera(byteData);
        debugPrint('$file');
        if (file.path.length > 0) {
          Fluttertoast.showToast(msg: '保存成功');
        } else {
          Fluttertoast.showToast(msg: '保存失败');
        }
      }
    

    capturePngToByteData生成图片具体实现

    /// 截屏图片生成图片流ByteData
      static Future<ByteData> capturePngToByteData(GlobalKey key) async {
        try {
          RenderRepaintBoundary boundary = key.currentContext.findRenderObject();
          double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比
          ui.Image image = await boundary.toImage(pixelRatio: dpr);
          ByteData _byteData =
              await image.toByteData(format: ui.ImageByteFormat.png);
          return _byteData;
        } catch (e) {
          debugPrint(e);
        }
        return null;
      }
    

    saveImageToCamera保存到相册具体实现

    /// 保存图片到相册
      static Future<File> saveImageToCamera(ByteData byteData) async {
        await handlePhotosPermission();
        
        Uint8List sourceBytes = byteData.buffer.asUint8List();
        String path = await ImagePickers.saveByteDataImageToGallery(sourceBytes);
        return File(path);
      }
    

    本文demo地址:https://github.com/Qson8/Image_capture_demo.git

    微信公众号:Hi Flutter
    关注可了解Flutter开发及IT科技资讯。
    问题或建议,请公众号留言。


    image

    相关文章

      网友评论

        本文标题:Flutter实现二维码海报图片截取并保存相册

        本文链接:https://www.haomeiwen.com/subject/vskwuhtx.html