一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
ImageFiltered
也是官方之后更新一批组件之一,用于对图像添加滤镜效果,比如图像的颜色矩阵变换、高斯模糊、图像矩阵变换等。注意,这不是仅指 Image
组件,而是对于任何
的 Widget
都适用。 在其诞生之前,有一个和其功能类似的组件 BackdropFilter ,但该组件的作用于是 背景
,如果想对特点的组件进行特效处理,就很不方便 。ImageFiltered
的引入,让这一切变得简单。
目前该组件已收录入 FlutterUnit ,大家可以在更新查阅,另外也项目中也开始考虑,将一些组件的枚举参数通过可切换
的方式进行操作。如果 FlutterUnit
对你有所帮助,欢迎在 github
中给个 star
以示支持~
| FlutterUnit 中 | 滤色效果 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | | |
一、认识 ImageFiltered 组件
在 ImageFiltered
组件中,只需要传入一个 ImageFilter
对象即可。该类型在就是 BackdropFilter
中的那位,所以 ImageFiltered
入手难度还是非常低的。
先来认识一下 ImageFilter
类,它是一个 抽象类
,但其中定义了三个 factory
命名构造,分别用于 模糊- blur
、矩阵变换 - matrix
和 多效果合成 - compose
,
我们知道,抽象类肯定是不能直接实例化的,在运行时肯定是特定实现类。如下所示,这三个 factory
命名构造,本质上是在构造下面红框中的三个 ImageFiltered
子类。另外注意一点 ColorFilter
也是 ImageFiltered
的实现类,所以我们可以通过它实现滤色效果。
二、ImageFiltered 的模糊效果
通过 ImageFilter.blur
可以构建出 _GaussianBlurImageFilter
,也就是高斯模糊图像过滤器。其中有三个参数,我们下面通过代码测试一下:
代码中的使用是非常简单的,把 ImageFiltered
套在任意目标组件上,提供 imageFilter
入参即可,如下是 _TargetContent
组件。
dart ImageFiltered( imageFilter: ImageFilter.blur( sigmaX: _sigmaX, sigmaY: _sigmaY, tileMode: _tileMode, ), child: const _TargetContent(), ),
1. 模糊的方向
下面通过左右两个 Slider
分别控制 sigmaX
和 sigmaY
的值。通过对比可以发现,sigmaX
决定水平方向上的模糊程度;sigmaY
决定竖直方向上的模糊程度:
| sigmaX:4.0 sigmaY:0 | sigmaX:0.0 sigmaY:4.0 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | | |
2. 模糊程度
如下的两组对比可以看出 sigmaX
和 sigmaY
的值越大,模糊程度就越高:
| sigmaX:2.5 sigmaY:2.5 | sigmaX:4.0 sigmaY:4.0 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | | |
3.平铺模式
最后还是一个 TileMode
枚举 ,有四种元素。在测试中通过点击对应的文字进行效果切换。从表面上似乎很难看出它们是干嘛的,其实打开布局边线就很容易明白。如下,红框是组件实际的占位,但 模糊效果
会有 sigmaX,sigmaY
的溢出,而 TileMode
就是确定溢出区域如何显示。
比如下面的 TileMode.mirror
效果是在溢出区域内,通过原图像进行镜像
显示:
TileMode.repeated
效果是在溢出区域内,通过原图像进行重复
显示:
另外 TileMode.clamp
是默认的类型,在 溢出区域内
每行的像素都取自边界,产生一直拉伸的效果。
TileMode.decal
效果是在溢出区域内,使用透明色。感觉这个效果是最自然的:
这就是通过 ImageFilter.blur
实现模糊的效果。
三、ImageFiltered 的矩阵变换效果
ImageFiltered.matrix
构造中,会构造 _MatrixImageFilter
对象,其中需要传入 Float64List
数组,并且长度是 16
。也就是一个 4*4
的矩阵。
当然,你可以直接写十六个数组,但通过 Matrix4
对象可以更方便的进行操作,通过 Matrix4
的 storage
可以获取 Float64List
数组。其是 Matrix4
本质上就是对这 16
个数字进行维护而已。
下面通过一个 Slider
控制旋转角度,简单实现一下选择效果。可以看出 变换中心
并不能组件的中心:
dart ImageFiltered( imageFilter: ImageFilter.matrix( Matrix4.rotationZ(_sigmaX/180*pi).storage ), child: const _TargetContent(), ),
另外,通过两帧的旋转对比,可以推断出变化中心是屏幕的左上角:
如果需要使 变换中心
在组件中心,需要进行额外的偏移处理,但这个尺寸需要进行计算。倒不如直接使用 Transform
组件比较方便,可以指定 变换中心
。
四、ColorFilter 与 ImageFiltered
ColorFilter
作为 ImageFilter
的实现类,自然也可以在 ImageFiltered
中使用。我们可以通过一个 5*4
的颜色矩阵对图像的色彩进行变换。比如下面的矩阵可以实现色彩的反转:
dart ColorFilter invert = const ColorFilter.matrix(<double>[ -1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0, ]);
至于变换的原理,在 《Flutter 绘制指南 - 妙笔生花》的第八章,有所介绍,这里就不引申了。
灰色
:
dart ColorFilter greyscale = const 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, ]);
暗色
dart ColorFilter darken = const ColorFilter.matrix(<double>[ 1, 0, 0, 0, -126.0, 0, 1, 0, 0, -126.0, 0, 0, 1, 0, -126.0, 0, 0, 0, 1, 0 ]);
棕褐色调
dart ColorFilter sepia = const 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, ]);
srgbToLinearGamma
和linearToSrgbGamma
另外 ColorFilter
中还提供了两个命名构造,效果如下,上来看像是对颜色的饱和度进行加重和减弱。
dart const ColorFilter.srgbToLinearGamma() const ColorFilter.linearToSrgbGamma()
| srgbToLinearGamma | linearToSrgbGamma | | ------------------------------------------------------------ | ------------------------------------------------------------ | | | |
五、源码实现简看
感觉 ImageFiltered
可以支持 ColorFilter
,这无疑是在抢 ColorFiltered
的饭碗。就好像在说,你能做的我也能做,你不能做的我还能做。
ImageFiltered
通过 _ImageFilterRenderObject
渲染对象实现功能:
_ImageFilterRenderObject
在绘制方法中,通过添加 ImageFilterLayer
层,为该层进行效果处理:
那么 ImageFiltered
组件的介绍就到这里,谢谢观看 ~