阅读 966

【Flutter 组件集录】 ImageFiltered 与 ColorFiltered

前言:

这是我参与8月更文挑战的第 29 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战,我准备在本月挑选 31 个以前没有介绍过的组件,进行全面分析和属性介绍。这些文章将来会作为 Flutter 组件集录 的重要素材。希望可以坚持下去,你的支持将是我最大的动力~

本系列组件文章列表
1.NotificationListener2.Dismissible3.Switch
4.Scrollbar5.ClipPath6.CupertinoActivityIndicator
7.Opacity8.FadeTransition9. AnimatedOpacity
10. FadeInImage11. Offstage12. TickerMode
13. Visibility14. Padding15. AnimatedContainer
16.CircleAvatar17.PhysicalShape18.Divider
19.Flexible、Expanded 和 Spacer 20.Card21.SizedBox
22.ConstrainedBox23.Stack24.Positioned
25.OverflowBox26.SizedOverflowBox27. DecoratedBox
28. BackdropFilter29.ImageFiltered 与 ColorFiltered

一、ImageFiltered 组件

1. 认识 ImageFiltered 组件

上一篇说了 BackdropFilter 组件,它可以在子组件下方添加一个过滤层,所以此效果无法作用于子组件。而 ImageFiltered 是将 过滤层 放在子组件上方,也就是过滤效果可以作用于子组件上。

它继承自 SingleChildRenderObjectWidget,必须传入 imageFilter 参数,类型为 ImageFilter。这和 BackdropFilter 组件中的 imageFilter 是一样的。


2. ImageFiltered 组件的使用

如下是通过 ImageFiltered 对图片进行模糊的效果,imageFilter 参数的使用和 BackdropFilter 一样,这里不再赘述。

1*12*23*35*5
class ImageFilteredDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ImageFiltered(
            imageFilter: ImageFilter.blur(
              sigmaX: 2,
              sigmaY: 2,
            ),
            child: Image.asset(
                'assets/images/sabar.webp',
                fit: BoxFit.cover,
                width: 150,
                height: 150,
            ),
    );
  }
}
复制代码

另外 ImageFiltered 并不局限于 Image 组件。如下将 FlutterUnit 整体使用 ImageFiltered 进行处理,这样全应用都会有模糊效果。虽然这么做没有什么太大的意义,只是说明 ImageFiltered 可以处理任意组件。

---
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  //滚动性能优化 1.22.0
  GestureBinding.instance?.resamplingEnabled = true;
  runApp(BlocWrapper(
    child: ImageFiltered(
      imageFilter: ImageFilter.blur(
        sigmaX: 2,
        sigmaY: 2,
      ),
      child: FlutterUnit(),
    ),
  ));
}
复制代码

3.ImageFiltered 组件源码实现

ImageFiltered 继承自 SingleChildRenderObjectWidget ,内部维护 _ImageFilterRenderObject 渲染对象来实现添加滤色器功能。


_ImageFilterRenderObject#paint 中创建 ImageFilterLayer 对象 layer,并将传入的 imageFilter 设置给 layer 。通过 context.pushLayer 添加一个层,实现滤色器功能。


二、ColorFiltered 组件

1.认识 ColorFiltered 组件

ColorFiltered 继承自 SingleChildRenderObjectWidget,必须传入 colorFilter 参数,类型为 ImageFilter


2. ColorFiltered 组件的使用

ColorFiltered 有四种构造方式,.srgbToLinearGamma.linearToSrgbGamma 是固定的处理效果;.mode 是通过颜色和混合模式进行着色处理。通过 .matrix 可以进行颜色的矩阵变换。这块比较复杂,不详细展开,感兴趣的可以看一下《Flutter 绘制指南 - 妙笔生花》 的第八章,有对着色器的详细介绍。

//srgbToLinearGamma
ColorFiltered(
  colorFilter: ColorFilter.srgbToLinearGamma(),
  child:  Image.asset(
    'assets/images/sabar.webp',
    fit: BoxFit.cover,
    width: 150,
    height: 150,
  ),
)
  
//linearToSrgbGamma
ColorFiltered(
  colorFilter: ColorFilter.linearToSrgbGamma(),
  child:  Image.asset(
    'assets/images/sabar.webp',
    fit: BoxFit.cover,
    width: 150,
    height: 150,
  ),
)
  
//.matrix
ColorFiltered(
  colorFilter: ColorFilter.matrix(<double>[
    1,0,0,0,110,
    0,1,0,0,110,
    0,0,1,0,110,
    0,0,0,1,0
  ]),
  child:  Image.asset(
    'assets/images/sabar.webp',
    fit: BoxFit.cover,
    width: 150,
    height: 150,
  ),
),
复制代码

同样 ColorFiltered 并不局限于 Image 组件。如下将 FlutterUnit 整体使用 ColorFiltered 进行灰色处理,这样全应用都会有着色效果,说明 ColorFiltered 可以处理任意组件。这在某些场景下还是非常有用的。

---
ColorFiltered(
  colorFilter: ColorFilter.matrix(<double>[
    0.2126, 0.7152, 0.0722, 0, 0,
    0.2126, 0.7152, 0.0722, 0, 0,
    0.2126, 0.7152, 0.0722, 0, 0,
    0,      0,      0,      1, 0,
  ]),
  child: FlutterUnit(),
),
复制代码

其实有了 matrix 可以操作颜色变换,就会有很多可发挥的空间,它又可以作用于任何组件,做出全局的怀旧色什么的也不是不可以。matrix 这东西,有着无限的可能。


3.ColorFiltered 组件源码实现

可能会有人担心性能什么的,其实看了这么多的 SingleChildRenderObjectWidget ,我们也能知道一些特点。ColorFiltered 是通过 _ColorFilterRenderObject 实现的。

在绘制时添加了一层 ColorFilterLayer ,进行着色处理。这就像是在眼前放一个红色的膜片,看到世界上所有的东西都带红色一样,而不是膜片拥有改变世界的能力,把世界上所有的东西真正被染成了红色。

ColorFiltered 也是一样,它只是一个遮罩层,并非所有的组件都一一被染成红色,不用顾虑太多。OpacityClipRectTransform 这类功能性的组件都是通过添加对应的层实现功能的,所以 ColorFilterLayer 也就是一个普通的 SingleChildRenderObjectWidget

那本文到这里就结束了,谢谢观看,明天见~

文章分类
Android