Flutter学习 ---- 屏幕截图和高斯模糊

本文介绍了如何在Flutter中实现屏幕截图并进行高斯模糊处理,通过使用StackBlur库进行图片模糊,以及使用FadeTransition实现Widget的淡入淡出切换。文章探讨了Flutter的开发体验和生态系统,强调其轻量、全面且稳定的特性。

废话不多说,先上本次要实现的效果图。
效果

Gif格式是渣像素,实际效果要自然的多。这个项目其实是看到小池记账小程序后实现的一个类似效果,小池比较闪光的一点就是这个主界面的动态高斯模糊效果,不过小池的动态模糊效果就不如Flutter可以做的这么自然流畅了,模糊时还是有肉眼可见的卡顿的。大家可以搜索小池记账对比一下,下面进入正文。

知识点

  1. Flutter中如何截取当前屏幕的Widget图片。
  2. Flutter如何对一张图片进行高斯模糊。
  3. 如何淡入淡出切换两个Widget。

Flutter截取当前屏幕的Widget图片

  1. 目前官网文档还没有相关的例子,正式发布的Beta3版本也没有公开的方法,但事实上,在未公开发布的Flutter v0.4.4中,已经有截取当前屏幕Widget图片的文档了,地址在这里。我们需要切换到当前的开发分支才能看到这个新的方法toImage()。你可以直接在Flutter的本地git仓库checkout到master分支,当然,也可以用下面更简单的方法,运行这两个命令,Flutter会自动切换到最新分支并下载依赖,到这里,准备工作就算完成了。
flutter channel master
flutter doctor -v
  1. 给需要截图的Widget包裹一个RepaintBoundary,如下示例代码:
class _PngHomeState extends State<PngHome> {
   
   
  GlobalKey globalKey = new GlobalKey();

  // 截图boundary,并且返回图片的二进制数据。
  Future<Uint8List> _capturePng() async {
    RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
    ui.Image image = await boundary.toImage();
    // 注意:png是压缩后格式,如果需要图片的原始像素数据,请使用rawRgba
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();
    return pngBytes;
  }

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      //globalKey用于识别
      key: globalKey,
      child: Center(
        child: FlatButton(
          child: Text('Hello World', textDirection: TextDirection.ltr),
          onPressed: _capturePng,
        ),
      ),
    );
  }

目前这个方法还是挺费时间的,大概在100ms左右才能得到截图,更别说我们还要对图片做处理,所以,尽管我对生成的图片做了缓存,但是第一次得到图片的时候,还是会有一小会的停顿(200-300ms)

对得到的图片进行高斯模糊

拿到了图片的二进制数据,怎么对其进行高斯模糊?搜索官网发现了一个很好的库:image,把它添加到项目中来,在pubspec.yaml中添加如下代码:

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.0
  image: "^1.1.32"

然后在项目中import,注意取一个别名,不要跟Flutter已有的Image库冲突:

impor
### 如何在 Flutter 中应用模糊效果而不影响背景 为了实现在 Flutter 应用中添加模糊效果的同时保持原有背景不受干扰,可以采用 `BackdropFilter` 组件来处理图像过滤操作。此组件允许对渲染层下方的内容施加滤镜效果,在本场景下即是指定高斯模糊。 当希望仅使特定区域变得模糊而不是整个屏幕或窗口时,应当注意将 `BackdropFilter` 的作用范围限定在一个容器内,并确保该容器背后存在可被模糊化的视觉内容[^1]。 下面是一个具体的例子展示如何做到这一点: ```dart import 'package:flutter/material.dart'; import 'dart:ui' as ui; class BlurryContainer extends StatelessWidget { @override Widget build(BuildContext context) { return Stack( children: [ // 原始背景图片或其他任何类型的背景 Image.network('https://example.com/background.jpg', fit: BoxFit.cover), Center( child: ClipRect( child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), child: Container( width: 200, height: 200, decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)), alignment: Alignment.center, child: Text('Blurry Area'), ), ), ), ) ], ); } } ``` 上述代码片段展示了通过设置 `sigmaX` `sigmaY` 参数控制水平方向垂直方向上的模糊强度;同时利用 `ClipRect` 来裁剪超出指定矩形框外的部分,从而使得只有定义好的区域内才会显示出模糊的效果。 对于 macOS 平台而言,如果目标是在整体界面上实现半透明带模糊特性的窗口,则可以在配置文件里调整根部件属性以启用这些特性[^2]。不过需要注意的是,这种方式适用于全局样式定制而非局部控件级别的设计需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值