flutter RepaintBoundary 截屏图片下载,保存图片不清晰的问题

flutter RepaintBoundary 截屏图片下载,保存图片不清晰的问题

  • 前言
  • 一、什么是RepaintBoundary
  • 二、RepaintBoundary 能干什么
  • 三、RepaintBoundary 保存图片模糊的问题
  • 四、RepaintBoundary 使用小demo
  • 总结


前言

在这里插入图片描述

最近工作中,突然遇到截屏保存图片的问题,但是保存下来的图片,一直都非常的模糊,最后看源码才发现,可以直接设置image 的pixelRatio分辨率来解决,下面是完整的图片截屏保存方法


一、什么是RepaintBoundary

RepaintBoundary是Flutter中的一个小部件(Widget),用于控制其子部件的重绘行为。当使用RepaintBoundary包裹子部件时,它将创建一个独立的绘制缓冲区,子部件在该缓冲区内进行绘制。当子部件进行重绘时,只有RepaintBoundary本身被标记为需要重绘,而不会影响其他的部件。

使用RepaintBoundary的主要目的是提高应用的性能。在某些情况下,应用中的部分界面元素可能会频繁地进行重绘,这可能会导致不必要的性能损耗。通过将这些部分包装在RepaintBoundary中,可以将其独立出来,避免不必要的重绘。

二、RepaintBoundary 能干什么

以下简单的说一下使用RepaintBoundary的情况:

  1. 自定义绘制:如果你有一个自定义的绘制部件,其绘制逻辑相对复杂且频繁进行,你可以将其包裹在RepaintBoundary中,以避免不必要的重绘。
  2. 部分更新:当你只需要更新应用界面的一部分时,你可以使用RepaintBoundary将该部分隔离出来,避免整个界面的重绘。

需要注意的是,过度使用RepaintBoundary可能会导致性能下降。因为每个RepaintBoundary都需要额外的内存和绘制操作,如果滥用,会增加内存占用和绘制的开销。因此,只有在真正需要优化特定部分的重绘行为时才应该使用RepaintBoundary。

三、RepaintBoundary 保存图片模糊的问题

在 Flutter 中使用 RepaintBoundary 组件来截图并保存为图片时,有几个常见的原因可能导致保存的图片模糊:

  1. 分辨率不足:如果截图的分辨率较低,保存的图片可能会出现模糊。你可以尝试增加截图的分辨率来解决这个问题。
  2. 图片压缩:在保存图片时,如果选择了高压缩率,可能会导致图片质量下降,从而出现模糊。确保使用适当的压缩参数或选项,以保持图片质量。
  3. 图片缩放:如果你在保存图片之前对截图进行了缩放操作,可能会导致图片模糊。尽量避免对截图进行额外的缩放处理,或者在缩放时使用高质量的算法。
  4. 设备像素密度:在高像素密度(例如 Retina 显示屏)的设备上,如果没有正确处理像素密度,可能会导致截图的模糊。确保在截图时考虑到设备的像素密度,并相应地设置分辨率或缩放比例。

四、RepaintBoundary 使用小demo

以下是一个示例代码,展示如何使用 RepaintBoundary 组件来截图并保存图片:

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';

class ScreenshotPage extends StatefulWidget {
  
  _ScreenshotPageState createState() => _ScreenshotPageState();
}

class _ScreenshotPageState extends State<ScreenshotPage> {
  GlobalKey _globalKey = GlobalKey();

  Future<Uint8List?> takeScreenshot() 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;
  }

  void saveScreenshot() async {
    Uint8List? screenshotBytes = await takeScreenshot();
    if (screenshotBytes != null) {
      final result = await ImageGallerySaver.saveImage(screenshotBytes);
      print(result); // 打印保存结果
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Screenshot'),
      ),
      body: Center(
        child: RepaintBoundary(
          key: _globalKey,
          child: Container(
            width: 200,
            height: 200,
            color: Colors.blue,
            child: Text(
              'Example',
              style: TextStyle(color: Colors.white, fontSize: 20),
              textAlign: TextAlign.center,
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: saveScreenshot,
        child: Icon(Icons.camera),
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: ScreenshotPage(),
  ));
}

上述示例中,我们使用 RenderRepaintBoundarytoImage() 方法来获取截图的 ui.Image 对象,然后通过 toByteData() 方法将其转换为字节数据(Uint8List),最后使用 ImageGallerySaver 插件保存图片。


总结

请注意,这只是一个基本示例,你可能需要根据你的具体需求进行调整。另外,确保你已在 pubspec.yaml 文件中添加了 image_gallery_saver 插件的依赖。

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

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

相关文章

超细,设计一个“完美“的测试用例,用户登录模块实例...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 好的测试用例一定…

Vite按需引入自定义组件unplugin-vue-components

1.安装插件 npm i unplugin-vue-components -D 2.vite.config.ts文件加如下代码 plugins: [vue({reactivityTransform: true}),Components({extensions: [vue, md],include: [/\.vue$/, /\.vue\?vue/, /\.md$/],dts: src/components.d.ts,deep: true, // 搜索子目录dirs: [s…

RabbitMQ-基础学习

在虚拟机上安装Erlang的GCC环境&#xff0c;装erlong&#xff0c;然后安装rabbitmq 参考&#xff1a;安装说明链接 安装web端面板 创建交换机 先学习一下工作模式&#xff08;详细介绍可见官网&#xff09; 上代码 1.Hello Word模式 写在测试类中&#xff1a; Providucer T…

Angular 调试工具(Augury)

目录 1、简介 2、检验代码 3、Angury 本地构建和安装 3.1 添加到Chrome 浏览器&#xff1a; 3.2 添加到Firefox浏览器 4、项目中对应的Npm脚本 5、Augury 三大主要功能 5.1 组件树&#xff08;Component Tree&#xff09; 5.1.1 Component Tree 5.2 路由树&#xff0…

【DBA课程-笔记】MongoDB入门到云上开发

课程目的&#xff1a;成为专业MongoDB的DBA nosql第一&#xff1a;MongoDB 一、讲师&#xff1a; 二、课程目录 第1章&#xff1a;MongoDB数据库入门 第2章&#xff1a;MongoDB数据数据查询与分析 第3章&#xff1a;MongoDB数据库核心知识 第4章&#xff1a;MongoDB数据库…

基于单片机智能加湿器 水位防干烧加湿器的设计与实现

功能介绍 以51/STM32单片机作为主控系统&#xff1b;LCD1602液晶显示当前温湿度&#xff0c;当前模式&#xff0c;湿度下限;按键设置湿度下限&#xff0c;当湿度低于下限时开启加湿器;水位传感器检查加湿器是否有水&#xff0c;如果没有水到话加湿器不进行工作&#xff0c;蜂鸣…

做题遇见的PHP函数汇总

mb_substr函数 mb_substr() 函数返回字符串的一部分&#xff0c;之前学过 substr() 函数&#xff0c;它只针对英文字符&#xff0c;如果要分割的中文文字则需要使用 mb_substr() 语法&#xff1a; mb_substr ( $str ,$start [, $length NULL [, $encoding mb_encoding() ]] …

ARM架构(寄存器点灯)

文章目录 前言一、LED原理图二、使用寄存器点灯的步骤三、如何操作寄存器四、实际操作1.使能GPIO端口2.将引脚设置为输出模式3.设置输出状态 五、全部代码总结 前言 本篇文章我们来讲解一下如何使用寄存器点亮一个LED灯&#xff0c;一般对于新人来说都是使用HAL库或者标准库来…

交通 | 针对Close-Enough旅行商问题的一种分支定界算法

论文解读​&#xff1a;王飞龙&#xff0c;曲晨辉 1、问题背景 \qquad 旅行商问题(TSP)是一种众所周知的路径问题。TSP的目标是在图 G ( V , E ) G(V,E) G(V,E)中找一条以场站为起终点的最短路&#xff0c;访问所有客户点 V V V&#xff0c;同时没有子环路。令 E E E表示网络中…

实训笔记7.4

实训笔记7.4 7.4一、座右铭二、IDEA集成开发环境的安装和使用三、DEBUG断点调试四、Java设计模式4.1 适配器模式4.2 动态代理模式4.3 单例设计模式 五、Java中网络编程5.1 网络编程三个核心要素5.2 TCP网络编程 六、基于网络编程的聊天系统6.1 需求分析6.2 系统设计6.2.1 概要设…

VirtualBox安装Ubuntu(22.04.2)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

RabbitMQ学习笔记9 TTL死信队列+延迟队列实战

我们去新建一个交换机&#xff1a; 然后我们再用这种方法直接创建一个队列&#xff1a; 点击bind这样我们的交换机和队列就绑定到一起了。 然后我们要新建普通队列&#xff0c;设置过期时间&#xff0c;指定死信交换机。 发布一条消息。 它会把队列传递到死信队列中去。

SpringBoot整合SpringSecurity认证与授权

唠嗑部分 在项目开发中&#xff0c;权限认证是很重要的&#xff0c;尤其是一些管理类的系统&#xff0c;对于权限要求更为严格&#xff0c;那么在Java开发中&#xff0c;常用的权限框架有哪些呢&#xff1f; 推荐的有两种&#xff0c;Shiro 与 SpringSecurity&#xff0c;当然…

GC回收器演进之路

目录 未来演进方向 历经之路 引用计数法 标记清除法 复制法 标记整理 分代式 三色标记法的诞生 三色标记法的基本概念 产生的问题 问题 1&#xff1a;浮动垃圾 问题 2&#xff1a;对象消失 遍历对象图不需要 STW 的解决方案 屏障机制 插入屏障&#xff08;Dijks…

故障:启动修复无法修复你的电脑

有台笔记本很久没用了无法开机了&#xff0c;还是用的win7的系统&#xff0c;开机后提示我使用启动修复&#xff0c;但是失败了&#xff0c;提示我启动修复无法修复你的电脑 启动修复无法修复你电脑怎么办_自动修复电脑未正确启动的解决方法&#xff0d;win7之家 1、上网查了下…

Mybatis-SQL分析组件 | 京东云技术团队

背景 大促备战&#xff0c;最大的隐患项之一就是慢sql&#xff0c;带来的破坏性最大&#xff0c;也是日常工作中经常带来整个应用抖动的最大隐患&#xff0c;而且对sql好坏的评估有一定的技术要求&#xff0c;有一些缺乏经验或者因为不够仔细造成一个坏的sql成功走到了线上&am…

基于单片机智能衣柜 智能衣橱 换气除湿制系统紫外线消毒的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;液晶显示当前衣柜温湿度和柜门开启关闭状态&#xff1b;按键设置当前衣柜湿度上限值、衣柜门打开和关闭&#xff0c;杀菌消毒&#xff1b;当湿度超过设置上限&#xff0c;继电器闭合开启风扇进行除湿&#xff1b;进行杀菌消毒时&am…

zk-IMG:对抗虚假信息

1. 引言 前序博客&#xff1a; ZKP图片授权——PhotoProof&#xff1a;proofs of permissible photo edits Daniel Kang等人2022年论文《ZK-IMG: Attested Images via Zero-Knowledge Proofs to Fight Disinformation》&#xff0c;在该论文中提供了一个简单的deep fake ima…

Web安全——渗透测试基础知识下

渗透测试基础 Web安全一、VMware虚拟机学习使用1、虚拟机简单介绍2、网络模式2.1 桥接网络&#xff08;Bridged Networking&#xff09;2.2 NAT模式2.3 Host-Only模式 3、通俗理解 二、Kali的2021安装与配置1、简单介绍2、Kali的版本3、配置3.1 安装虚拟机open-vm-tools-deskto…

IDEA中集成zookeeper的插件

IDEA中集成zookeeper的插件 一、IDEA中集成插件 搜索插件并安装&#xff1a; 安装完成&#xff0c;重启IDEA 配置zk集群 连接成功
最新文章