likes
comments
collection
share

【Flutter 组件集录】ImageFiltered 图像滤镜

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

FlutterUnit 中滤色效果
【Flutter 组件集录】ImageFiltered 图像滤镜【Flutter 组件集录】ImageFiltered 图像滤镜

一、认识 ImageFiltered 组件

ImageFiltered 组件中,只需要传入一个 ImageFilter 对象即可。该类型在就是 BackdropFilter 中的那位,所以 ImageFiltered 入手难度还是非常低的。

【Flutter 组件集录】ImageFiltered 图像滤镜


先来认识一下 ImageFilter 类,它是一个 抽象类 ,但其中定义了三个 factory 命名构造,分别用于 模糊- blur矩阵变换 - matrix多效果合成 - compose

【Flutter 组件集录】ImageFiltered 图像滤镜


我们知道,抽象类肯定是不能直接实例化的,在运行时肯定是特定实现类。如下所示,这三个 factory 命名构造,本质上是在构造下面红框中的三个 ImageFiltered 子类。另外注意一点 ColorFilter 也是 ImageFiltered 的实现类,所以我们可以通过它实现滤色效果。

【Flutter 组件集录】ImageFiltered 图像滤镜


二、ImageFiltered 的模糊效果

通过 ImageFilter.blur 可以构建出 _GaussianBlurImageFilter ,也就是高斯模糊图像过滤器。其中有三个参数,我们下面通过代码测试一下:

【Flutter 组件集录】ImageFiltered 图像滤镜

代码中的使用是非常简单的,把 ImageFiltered 套在任意目标组件上,提供 imageFilter 入参即可,如下是 _TargetContent 组件。

ImageFiltered(
  imageFilter: ImageFilter.blur(
    sigmaX: _sigmaX,
    sigmaY: _sigmaY,
    tileMode: _tileMode,
  ),
  child: const _TargetContent(),
),

1. 模糊的方向

下面通过左右两个 Slider 分别控制 sigmaXsigmaY 的值。通过对比可以发现,sigmaX 决定水平方向上的模糊程度;sigmaY 决定竖直方向上的模糊程度:

sigmaX:4.0 sigmaY:0sigmaX:0.0 sigmaY:4.0
【Flutter 组件集录】ImageFiltered 图像滤镜【Flutter 组件集录】ImageFiltered 图像滤镜

2. 模糊程度

如下的两组对比可以看出 sigmaXsigmaY 的值越大,模糊程度就越高:

sigmaX:2.5 sigmaY:2.5sigmaX:4.0 sigmaY:4.0
【Flutter 组件集录】ImageFiltered 图像滤镜【Flutter 组件集录】ImageFiltered 图像滤镜

3.平铺模式

最后还是一个 TileMode枚举 ,有四种元素。在测试中通过点击对应的文字进行效果切换。从表面上似乎很难看出它们是干嘛的,其实打开布局边线就很容易明白。如下,红框是组件实际的占位,但 模糊效果 会有 sigmaX,sigmaY 的溢出,而 TileMode 就是确定溢出区域如何显示。

比如下面的 TileMode.mirror 效果是在溢出区域内,通过原图像进行镜像显示:

【Flutter 组件集录】ImageFiltered 图像滤镜

TileMode.repeated 效果是在溢出区域内,通过原图像进行重复显示:

【Flutter 组件集录】ImageFiltered 图像滤镜


另外 TileMode.clamp 是默认的类型,在 溢出区域内 每行的像素都取自边界,产生一直拉伸的效果。

【Flutter 组件集录】ImageFiltered 图像滤镜


TileMode.decal 效果是在溢出区域内,使用透明色。感觉这个效果是最自然的:

【Flutter 组件集录】ImageFiltered 图像滤镜

这就是通过 ImageFilter.blur 实现模糊的效果。


三、ImageFiltered 的矩阵变换效果

ImageFiltered.matrix 构造中,会构造 _MatrixImageFilter 对象,其中需要传入 Float64List 数组,并且长度是 16 。也就是一个 4*4 的矩阵。

![image-20220423084947599](/Users/mac/Library/Application Support/typora-user-images/image-20220423084947599.png)

当然,你可以直接写十六个数组,但通过 Matrix4 对象可以更方便的进行操作,通过 Matrix4storage 可以获取 Float64List 数组。其是 Matrix4 本质上就是对这 16 个数字进行维护而已。

【Flutter 组件集录】ImageFiltered 图像滤镜


下面通过一个 Slider 控制旋转角度,简单实现一下选择效果。可以看出 变换中心 并不能组件的中心:

【Flutter 组件集录】ImageFiltered 图像滤镜

ImageFiltered(
  imageFilter: ImageFilter.matrix(
    Matrix4.rotationZ(_sigmaX/180*pi).storage
  ),
  child: const _TargetContent(),
),

另外,通过两帧的旋转对比,可以推断出变化中心是屏幕的左上角:

【Flutter 组件集录】ImageFiltered 图像滤镜

如果需要使 变换中心 在组件中心,需要进行额外的偏移处理,但这个尺寸需要进行计算。倒不如直接使用 Transform 组件比较方便,可以指定 变换中心


四、ColorFilter 与 ImageFiltered

ColorFilter作为 ImageFilter 的实现类,自然也可以在 ImageFiltered 中使用。我们可以通过一个 5*4 的颜色矩阵对图像的色彩进行变换。比如下面的矩阵可以实现色彩的反转:

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 组件集录】ImageFiltered 图像滤镜


  • 灰色
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,
]);

【Flutter 组件集录】ImageFiltered 图像滤镜


  • 暗色
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
]);

【Flutter 组件集录】ImageFiltered 图像滤镜


  • 棕褐色调
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,
]);

【Flutter 组件集录】ImageFiltered 图像滤镜


  • srgbToLinearGammalinearToSrgbGamma

另外 ColorFilter 中还提供了两个命名构造,效果如下,上来看像是对颜色的饱和度进行加重和减弱。

const ColorFilter.srgbToLinearGamma()
const ColorFilter.linearToSrgbGamma()
srgbToLinearGammalinearToSrgbGamma
【Flutter 组件集录】ImageFiltered 图像滤镜【Flutter 组件集录】ImageFiltered 图像滤镜

五、源码实现简看

感觉 ImageFiltered 可以支持 ColorFilter ,这无疑是在抢 ColorFiltered 的饭碗。就好像在说,你能做的我也能做,你不能做的我还能做。

【Flutter 组件集录】ImageFiltered 图像滤镜


ImageFiltered 通过 _ImageFilterRenderObject 渲染对象实现功能:

【Flutter 组件集录】ImageFiltered 图像滤镜

_ImageFilterRenderObject 在绘制方法中,通过添加 ImageFilterLayer 层,为该层进行效果处理:

【Flutter 组件集录】ImageFiltered 图像滤镜

那么 ImageFiltered 组件的介绍就到这里,谢谢观看 ~

转载自:https://juejin.cn/post/7089628752400875550
评论
请登录