【Flutter 组件集录】 ImageFiltered 与 ColorFiltered

2022-03-18 15:52:47 浏览数 (1)

一、ImageFiltered 组件
1. 认识 ImageFiltered 组件

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

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

2. ImageFiltered 组件的使用

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

代码语言:javascript复制
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 可以处理任意组件.

代码语言:javascript复制
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 绘制指南 - 妙笔生花》 的第八章,有对着色器的详细介绍。

代码语言:javascript复制
//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 可以处理任意组件。这在某些场景下还是非常有用的。

代码语言:javascript复制
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

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

0 人点赞