flutter生成二维码并截图保存到图库

在这里插入图片描述在这里插入图片描述

引入库:flutter_screenutil、image_gallery_saver、qr_flutter弹窗布局

import 'dart:async';
import 'dart:typed_data';
import 'package/generated/l10n.dart';
import 'package:jade/configs/PathConfig.dart';
import 'package:jade/utils/ImageWaterMarkUtil.dart';
import 'package:jade/utils/JadeColors.dart';
import 'package:jade/utils/Utils.dart';
import 'package:util/easy_loading_util.dart';
import 'package:util/navigator_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:qr_flutter/qr_flutter.dart';import 'dart:ui' as ui;
/*
* 普通说明弹窗(可隐藏取消按钮)
* */
Widget productQrcodeDialog (
    BuildContext context,
    { String descTitle,
      String subTitle,
      String desc,
      String qrStr,
      GlobalKey globalKey,
      Function callback,
      Function cancelCallback,
      bool showCancel = false,
      String sureBtnText,
      Color sureBtnTextColor
    }){
  return UnconstrainedBox(
      child: Container(
        alignment: Alignment.center,
        width: Utils().screenWidth(context)*0.8,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            if(descTitle != null)
              Container(
                  margin: EdgeInsets.only(top: 50.w),
                  child: Text(descTitle??'',style: TextStyle(color: JadeColors.grey_2,fontSize: 38.sp,fontWeight: FontWeight.w600))
              ),
            if(subTitle != null)
              Container(
                  margin: EdgeInsets.only(top: 20.w),
                  child: Text(subTitle,style: TextStyle(color: JadeColors.grey,fontSize: 24.sp))
              ),
            if(desc != null)
              Container(
                  margin: EdgeInsets.only(top: 30.w,bottom: 30.w),
                  padding: EdgeInsets.symmetric(horizontal: 30.w),
                  child: Text(desc,style: TextStyle(color: JadeColors.grey_2,fontSize: 30.sp),maxLines: 300,textAlign: TextAlign.center,)
              ),
            RepaintBoundary(
                key: globalKey,
                child: Container(
                    width: Utils().screenWidth(context)*0.6,
                    height: Utils().screenWidth(context)*0.6,
                    decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(10),
                        border: Border.all(width: 1,color: JadeColors.blue_2)
                    ),
                    child: Stack(
                      alignment: Alignment.center,
                      children: [
                        QrImage(
                          padding: EdgeInsets.all(11.w),
                          data: qrStr,
                          version: QrVersions.auto,
                          size: Utils().screenWidth(context) * 0.6,
                        ),
                        Container(
                          width: 60.w,
                          height: 60.w,
                          decoration: BoxDecoration(
                              color: Colors.white,
                              borderRadius: BorderRadius.circular(5),
                              border: Border.all(width: 1.w,color:Colors.white)
                          ),
                          child: Utils().roundedImage(PathConfig.httpAppLogo, 5),
                        )
                      ],
                    )
                ),
            ),
            Container(
              margin: EdgeInsets.only(top: 40.w),
              height: 0.5,color: JadeColors.grey_13,
            ),
            Container(
              height: 92.w,
              child: Row(
                children: [
                  if(showCancel)
                    Expanded(child: GestureDetector(
                      child: Container(
                          color: Colors.transparent,
                          alignment: Alignment.center,
                          child: Text(S.current.quxiao,style: TextStyle(color: JadeColors.grey,fontSize: 34.sp,fontWeight: FontWeight.w300))
                      ),
                      onTap: (){
                        NavigatorUtil.pop();
                        if(cancelCallback != null){
                          cancelCallback();
                        }
                      },
                    )),
                  if(showCancel)
                    Container(width: 0.5,color: JadeColors.grey_13,height: double.infinity,),
                  Expanded(child: GestureDetector(
                    child: Container(
                      alignment: Alignment.center,
                      color: Colors.transparent,
                      child: Text(sureBtnText??S.current.close,style: TextStyle(color: sureBtnTextColor??Colors.blue,fontSize: 34.sp,fontWeight: FontWeight.w600),textAlign: TextAlign.center),
                    ),
                    onTap: () async {
                      _saveScreenshot(globalKey);
                      if(callback != null){
                        callback();
                      }
                    },
                  )),
                ],
              ),
            )
          ],
        ),
      )
  );
}

  Future<Uint8List> takeScreenshot(GlobalKey _globalKey) async {
  try {
    RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject() as RenderRepaintBoundary;
    ui.Image image = await boundary.toImage(pixelRatio: 3.0); // 调整分辨率以适应高像素密度设备
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    if (byteData != null) {
      Uint8List pngBytes = byteData.buffer.asUint8List();
      return pngBytes;
    }
  } catch (e) {
    print(e);
  }
  return null;
}

 _saveScreenshot(GlobalKey globalKey) async {
  Uint8List screenshotBytes = await takeScreenshot(globalKey);
  if (screenshotBytes != null) {
    final result = await ImageGallerySaver.saveImage(screenshotBytes);
    print('result= $result');// 打印保存结果
    esLoadingToast('已保存截图至本地');
  }else{
    esLoadingToast('截图保存失败');
  }
  NavigatorUtil.pop();
}

弹窗

 /*
  * 产品二维码弹窗
  * */
  Future<void> productQrCodeDialog(BuildContext context,{String descTitle,String subTitle,String desc,String qrStr,GlobalKey globalKey,Function callback,Function cancelCallback,bool showCancel = false,String sureBtnText,Color sureBtnTextColor}) async {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return productQrcodeDialog(context,descTitle: descTitle,subTitle: subTitle,desc: desc,qrStr: qrStr,globalKey: globalKey,showCancel: showCancel,sureBtnText: sureBtnText,sureBtnTextColor:sureBtnTextColor,callback: callback,cancelCallback : cancelCallback);
        });
  }

调用

GlobalKey _globalKey = new GlobalKey();
GestureDetector(
child:_btnView(),
onTap: (){
productQrCodeDialog(context,
   descTitle: '产品二维码',
   desc: '请保存下载该二维码并打印,随同产品一起寄送至站点。',
   qrStr: '二维码的内容',
   globalKey: _globalKey,
   showCancel: true,
   sureBtnText: '下载',
    sureBtnTextColor: JadeColors.grey_2,
    callback: (){}
  );
   }
}
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/497434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

车载以太网AVB交换机 gptp透明时钟 8口 千兆/百兆可切换 SW1100TR

SW1100车载以太网交换机 一、产品简要分析 8端口千兆和百兆混合车载以太网交换机&#xff0c;其中包含2个通道的1000BASE-T1采用罗森博格H-MTD接口&#xff0c;5通道100BASE-T1泰科MATEnet接口和1个通道1000BASE-T标准以太网(RJ45接口)&#xff0c;可以实现车载以太网多通道交…

Flink系列之:Flink SQL Gateway

Flink系列之&#xff1a;Flink SQL Gateway 一、Flink SQL Gateway二、部署三、启动SQL Gateway四、运行 SQL 查询五、SQL 网关启动选项六、SQL网关配置七、支持的端点 一、Flink SQL Gateway SQL 网关是一项允许多个客户端从远程并发执行 SQL 的服务。它提供了一种简单的方法…

Unity图集编辑器

图集编辑器 欢迎使用图集编辑器新的改变编辑器图片 欢迎使用图集编辑器 Unity图集操作很是费劲 无法批量删除和添加图集中的图片 新的改变 自己写了一个图集编辑器 客&#xff1a; 支持批量删除 左键点击图片代表选中 右键点击图标定位到资产支持批量添加 选中图片拖拽到编…

Linux 系统 部署weblogic(新手版)

Linux 系统 部署weblogic&#xff08;新手版&#xff09; 一、 1、如果原环境有jdk则需要卸载。 先用命令查看 rpm -qa|grep java 如果有jdk则需要卸载rpm -e --nodeps java-1.7.0-openjdk-1.7.0.191-2.6.15.5.el7.x86_64rpm -e --nodeps java-1.8.0-openjdk-headl…

京东云0基础搭建帕鲁服务器_4核16G和8核32G幻兽帕鲁专用服务器

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云atengyun.…

【Java面试题】Redis上篇(基础、持久化、底层数据结构)

文章目录 基础1.什么是Redis?2.Redis可以用来干什么&#xff1f;3.Redis的五种基本数据结构&#xff1f;4.Redis为什么这么快&#xff1f;5.什么是I/O多路复用&#xff1f;6.Redis6.0为什么使用了多线程&#xff1f; 持久化7.Redis的持久化方式&#xff1f;区别&#xff1f;8.…

【JavaEE】初识线程,线程与进程的区别

文章目录 ✍线程是什么&#xff1f;✍线程和进程的区别✍线程的创建1.继承 Thread 类2.实现Runnable接口3.匿名内部类4.匿名内部类创建 Runnable ⼦类对象5.lambda 表达式创建 Runnable ⼦类对象 ✍线程是什么&#xff1f; ⼀个线程就是⼀个 “执行流”. 每个线程之间都可以按…

Github 2024-03-28Go开源项目日报Top10

根据Github Trendings的统计,今日(2024-03-28统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目9非开发语言项目1Ollama: 本地大型语言模型设置与运行 创建周期:248 天开发语言:Go协议类型:MIT LicenseStar数量:42421 个Fork数量:…

vue组件弹窗窗

import { createApp } from vue; import { Popup } from vant;const app createApp(); app.use(Popup); 有这样的一个效果 在手机上很美观 不错 建议大家使用

HarmonyOS实战开发-实现一个计步器卡片应用

介绍 本篇Codelab基于Stage模型实现带有卡片的计步应用&#xff0c;用于介绍卡片的开发及生命周期实现。需要完成以下功能&#xff1a; 消息通知栏&#xff0c;通知用户今天所行走步数。元服务卡片&#xff0c;在桌面上添加2x2或2x4规格元服务卡片&#xff0c;能看到步数变化…

论文问卷的六类分析思路

很多同学在写论文时&#xff0c;会选择通过收集问卷来获取研究所需的数据。然而&#xff0c;问卷收集完成后&#xff0c;如何对这些数据进行有效的分析&#xff0c;成为了一个重要的问题。这么多的问卷数据摆在面前&#xff0c;该如何进行分析呢&#xff1f; SPSSAU从问卷设计…

docker 部署 gitlab-ce 16.9.1

文章目录 [toc]拉取 gitlab-ce 镜像创建 gitlab-ce 持久化目录启停脚本配置配置 gitlab-ce编辑 gitlab-ce 配置文件重启 gitlab-ce配置 root 密码 设置中文 gitlab/gitlab-ce(需要科学上网) 拉取 gitlab-ce 镜像 docker pull gitlab/gitlab-ce:16.9.1-ce.0查看镜像是不是有 Vo…

图论之路径条数专题

一直忙着金工实习蓝桥杯&#xff0c;好久没有看图论了&#xff0c;今天就小试几题享受下被虐的快感。 1.最短路拓扑 首先来几个结论&#xff1a; 1.最短路图没有环&#xff08;可以用反证法证明&#xff09; 2.dis[u]edge[u,v]dis[v]&#xff0c;那么u,v端点的边一定在最短路…

【已修复】iPhone13 Pro 长焦相机水印(黑斑)修复 洗水印

iPhone13 Pro 长焦相机水印&#xff08;黑斑&#xff09;修复 洗水印 问题描述 iPhone13 Pro 后摄3倍相机有黑色斑点&#xff08;水印&#xff09;&#xff0c;如图所示&#xff0c; 后摄相机布局如图所示&#xff0c; 修复过程 拆机过程有风险&#xff0c;没有把握最好不要…

Git--08--Git分支合并操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Git分支合并操作案例流程客户端&#xff1a;GitExtensions操作步骤&#xff1a;A操作步骤&#xff1a;B操作步骤&#xff1a;C操作步骤&#xff1a;D操作步骤&#…

NanoMQ的安装与部署

本文使用docker进行安装&#xff0c;因此安装之前需要已经安装了docker 拉取镜像 docker pull emqx/nanomq:latest 相关配置及密码认证 创建目录/usr/local/nanomq/conf以及配置文件nanomq.conf、pwd.conf # # # # MQTT Broker # # mqtt {property_size 32max_packet_siz…

每日一题--最长连续序列

洛阳春-岑参 人到洛阳花似锦&#xff0c;偏我来时不逢春。 谁道三冬无春色&#xff0c;冰山高处万里银 目录 题目描述 思路分析 方法及其时间复杂度 法一 暴力枚举&#xff1a; 法二 哈希表遍历&#xff1a; 法三 并查集&#xff1a; 个人总结 题目描述 128. 最长连续序…

【网安小白成长之路】3.MySQL环境配置以及常用命令(增删改查)

&#x1f42e;博主syst1m 带你 acquire knowledge&#xff01; ✨博客首页——syst1m的博客&#x1f498; &#x1f51e; 《网安小白成长之路(我要变成大佬&#x1f60e;&#xff01;&#xff01;)》真实小白学习历程&#xff0c;手把手带你一起从入门到入狱&#x1f6ad; &…

Day53:WEB攻防-XSS跨站SVGPDFFlashMXSSUXSS配合上传文件添加脚本

目录 MXSS UXSS&#xff1a;Universal Cross-Site Scripting HTML&SVG&PDF&SWF-XSS&上传&反编译(有几率碰到) SVG-XSS PDF-XSS Python生成XSS Flash-XSS 知识点&#xff1a; 1、XSS跨站-MXSS&UXSS 2、XSS跨站-SVG制作&配合上传 3、XSS跨站-…

项目模块—实现抑郁测评(小程序)

script <script setup> import { ref } from "vue";//控制轮播图页码 let current ref(0);//答题逻辑 const add (value) > {if (current.value < 9) {current.value current.value 1;} else {uni.switchTab({url: "/pages/my/my",});} }…