likes
comments
collection
share

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

作者站长头像
站长
· 阅读数 10

前言

之前我们聊过 Image ,聊过给图片设置颜色,以及各种混合算法的使用,今天我们聊聊 Flutter 中各种过滤器的使用详解。

ColorFiltered(颜色过滤器)

看名字就知道是增加颜色滤镜效果的,下面先回忆一下我们之前聊的 Image 中设置颜色。

  • 一张正常的图片
Image.asset(
  'assets/images/img_03.jpeg',
  width: 375,
  height: 240,
  fit: BoxFit.cover,
)

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

  • 设置一个颜色
Image.asset(
  'assets/images/img_03.jpeg',
  width: 375,
  height: 240,
  fit: BoxFit.cover,
  color: Colors.pink,
)

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

  • 设置混合模式
Image.asset(
  'assets/images/img_03.jpeg',
  width: 375,
  height: 240,
  fit: BoxFit.cover,
  color: Colors.pink,
  colorBlendMode: BlendMode.color,
)

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets最终我们就合成一张这样带滤镜效果

追踪源码

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets我我们持续追踪源码到 RenderImage 类中,可以看到最终也是创建了一个 ColorFilter

简单使用

上面只是对 Image 增加滤镜效果,如果我们要对 Widget 增加滤镜效果呢?这时就需要用到 ColorFiltered 了,下面我们看看怎么使用吧

ColorFiltered(
  // 添加颜色过滤器
  colorFilter: ColorFilter.mode(
    // 设置颜色
    Colors.grey,
    // 设置混合模式
    BlendMode.saturation,
  ),
  child: ImageDescWidget(),
)
滤镜前滤镜后滤镜后-粉色
Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter WidgetsFlutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter WidgetsFlutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

其他构建方法

除了 ColorFilter.mode 我们如果翻看 ColorFilter 的源码,还会发现如下的几种构建方法

  • ColorFilter.linearToSrgbGamma()

构造一个将 sRGB 伽马曲线应用于 RGB 的滤色器通道

ColorFiltered(
  colorFilter: ColorFilter.linearToSrgbGamma(),
  child: ImageDescWidget(),
)
  • 效果

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

  • ColorFilter.srgbToLinearGamma()

创建一个滤色器,将 sRGB 伽马曲线的反转应用于 RGB 通道

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

  • ColorFilter.matrix

构造一个通过5x5矩阵变换颜色的滤色器

// 通过矩阵转换为颜色过滤器
const ColorFilter sepia = ColorFilter.matrix(<double>[
     0.393, 0.769, 0.189, 0, 0,
     0.349, 0.686, 0.168, 0, 0,
     0.272, 0.534, 0.131, 0, 0,
     0,     0,     0,     1, 0,
   ]);
ColorFiltered(
  colorFilter: sepia,
  child: ImageDescWidget(),
)
  • 效果

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

提问一下

如果现在 PM 要求你在特殊节日,统一给 App 设置为灰色你会怎么做呢?

实现代码

// 套在 App 的最外层
ColorFiltered(
  colorFilter: ColorFilter.mode(
    // 设置混合颜色和模式
    Colors.grey,
    BlendMode.saturation,
  ),
  child: MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: MyHomePage(title: 'Flutter Widgets'),
  ),
)

运行效果

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

ImageFiltered(图片过滤器)

不要被这个名字所迷惑,上面我们也看到了,Image 的着色器是通过 ColorFilter 来处理的,在 Flutter 中万物皆 Widget ,所以这里的 ImageFiltered 并不是说作用于图片的,只是有些通常我们应用的图片的过滤器在这里实现了。

ImageFilter.blur(模糊过滤器)

Flutter 中是如何给 Widget 添加模糊效果呢?就是使用这个,下面我们来看看怎么使用吧

  • 代码实现
ImageFiltered(
  // 设置模糊过滤器
  imageFilter: ImageFilter.blur(
    sigmaX: 4,
    sigmaY: 4,
    // tileMode: TileMode.clamp,
    // tileMode: TileMode.decal,
    // tileMode: TileMode.mirror,
    // tileMode: TileMode.repeated,
  ),
  child: ImageWidget(),
)
  • 预览效果 | 原图 | 模糊度 4 | 模糊度 6 | | --- | --- | --- | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets |

这里可以看出随着模糊度的增加,Widget 大小也随着向外扩展响应的半径距离,填充方式似乎大体看这不是等比缩放拉伸

  • tileMode - 平铺方式 | TileMode.clamp(默认) | TileMode.decal | | :---: | :---: | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter WidgetsFlutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets超出区域取边缘最接近的颜色平铺 | 超出区域梯度透明 | | TileMode.mirror | TileMode.repeated | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter WidgetsFlutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets超过区域与区域内呈来回镜像 | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter WidgetsFlutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets超过区域重复平铺 |

ImageFilter.matrix(矩阵过滤器)

这里可以通过矩阵的转换来实现,平移、缩放、旋转、倾斜的一些列操作

  • 代码实现
ImageFiltered(
  // 缩放
  imageFilter: ImageFilter.matrix(Matrix4.diagonal3Values(2, 2, 0).storage),
  // 倾斜
  // imageFilter: ImageFilter.matrix(Matrix4.skewY(pi / 8).storage),
  child: ImageWidget(),
  // Widget 效果
  // child: ImageDescWidget(),
)
  • 效果 | 缩放 | 倾斜 | | :---: | :---: | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets |

  • Widget 效果 | 缩放 | 倾斜 | | :---: | :---: | | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets | Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets |

ImageFilter.compose(组合过滤器)

上面我们聊的是单一的过滤器效果,很多情况下我们需要组合使用,这时就可以用到这个啦,我们直接看效果

  • 上代码
ImageFiltered(
  imageFilter: ImageFilter.compose(
    // 模糊
    outer: ImageFilter.blur(
      sigmaX: 4,
      sigmaY: 4,
    ),
    // 倾斜
    inner: ImageFilter.matrix(Matrix4.skewY(pi / 8).storage),
  ),
  child: ImageDescWidget(),
)
  • 看效果

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

BackdropFilter(背景过滤器)

上面的内容都是对整个 Widget 进行添加过滤器,很多时候我们,如果我们要实现背景滤镜的效果,就需要添加 Stack 来实现了

看源码

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

可以看到源码非常简单,其中过滤器直接是 ImageFilter 过滤器,所以上面聊过的过滤器都可以使用。

上代码

Stack(
  alignment: Alignment.bottomCenter,
  children: [
    // 背景
    ImageWidget(),
    // 添加剪裁
    ClipRect(
      child: BackdropFilter(
        // 模糊过滤器
        filter: ImageFilter.blur(
          sigmaX: 4,
          sigmaY: 4,
        ),
        // 设置子项
        child: Container(
          color: Colors.white.withOpacity(0.4),
          alignment: Alignment.center,
          padding: const EdgeInsets.all(6),
          child: Text(
            '🌸 樱花 🌸',
            style: TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    ),
  ],
)

看效果

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

  • 如果我们不添加剪裁

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

  • 如果改成 ImageFiltered
Stack(
  alignment: Alignment.bottomCenter,
  children: [
    // 背景
    ImageWidget(),
    // 添加剪裁
    ImageFiltered(
      // 模糊过滤器
      imageFilter: ImageFilter.blur(
        sigmaX: 0.5,
        sigmaY: 0.5,
      ),
      // 设置子项
      child: Container(
        color: Colors.white.withOpacity(0.4),
        alignment: Alignment.center,
        padding: const EdgeInsets.all(6),
        child: Text(
          '🌸 樱花 🌸',
          style: TextStyle(
            color: Colors.white,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    ),
  ],
)
  • 效果如下

Flutter 中 ColorFiltered、ImageFiltered、BackdropFilter的使用详解 | Flutter Widgets

BackdropFilter 和 ImageFiltered 的区别

对比项BackdropFilterImageFiltered
作用对象背景内容子项整体
作用范围整体背景,缩小需要加剪裁子项大小

源码仓库

基于 Flutter 🔥 最新版本

参考链接

关注专栏

  • 此文章已收录到下面👇 的专栏,可以直接关注
  • 更多文章继续阅读|系列文章持续更新

👏 欢迎点赞➕收藏➕关注,有任何问题随时在下面👇评论,我会第一时间回复哦