前语

继续咱们 Flutter 绘图相关的介绍,本篇咱们引入一位重量级主角 —— 灭霸。通过绘图的色彩过滤器,咱们要给灭霸点色彩看看。通过本篇,你会了解到如下内容:

  • ColorFilter 色彩过滤器的介绍;
  • 五颜六色图片转换为灰度图;
  • 通过矩阵运算构建自定义的色彩过滤器。

ColorFilter 色彩过滤器

其实咱们之前在给小姐姐的照片调个色彩滤镜有介绍过色彩滤镜,在 Flutter 中提供了一个 ColorFiltered 的组件,能够将色彩过滤器运用到其子组件上。实践上,色彩过滤器便是对一个图层的每个像素的色彩(包含透明度)进行数学运算,改动像素的色彩来完成特定的作用。数学公式如下:

给灭霸点色彩看看

在 Flutter 中,ColorFilter 类的继承自 ImageFilter,像 ImageFilter 一样,也只提供了命名结构函数,一共有四个命名结构函数,分别如下:

  • ColorFilter.mode(Color color, BlendMode mode):按拟定的混合形式(blend mode),将色彩混入到绘制的目标中。能够理解为图画的色值调整,咱们能够用一个指定的色彩调整原图,调整的形式有很多种,详细能够查看 BlendMode 枚举。
  • ColorFilter.linearToSrgbGamma():将一个 SRGB 的 gamma 曲线运用到 RGB 色彩通道中。
  • ColorFilter.srgbToLinearGamma()ColorFilter.linearToSrgbGamma()的反向进程。
  • ColorFilter.matrix(List<double> matrix):运用一个矩阵做色彩改换,也便是咱们上面说的矩阵,这是最通用的版别,要什么作用能够自己构建对应的矩阵。

这儿说一下 SRGB 的 gamma 曲线的用处。咱们人眼在显示屏中对图片进行调色等操作时,是依照线性空间的角度进行的,但显示器是在gamma空间中的,那么图画在计算机中的存储一般都应该是在 gamma 空间下了。也便是计算机存储的对错线性的,可是给咱们展示的时分要转为线性的。因而,关于一张图画,可能是线性的也可能是 gamma 空间的,这个时分为了一致可能就需要进行转换,那就会用到linearToSrgbGammasrgbToLinearGamma两个色彩过滤器。

五颜六色图片转成灰色图片

五颜六色图片转变为灰色图片有很2种办法,最简略的办法是运用ColorFilter.mode,第一个参数色彩挑选灰色或黑色,然后 第二个参数挑选 BlendMode.color 或者挨近的作用(比方 huesaturation)。BlendMode.color 是取源图的色彩和饱和度,然后取目标(即要改动的图片)的亮度。因而,假如咱们想更改一张图片的色彩,用这种方式最好了。下面是对应的完成代码和改换前后的比照图。

var paint = Paint();
paint.colorFilter = ColorFilter.mode(Colors.grey, BlendMode.color);
canvas.drawImageRect(
  bgImage,
  Rect.fromLTRB(0, 0, bgImage.width.toDouble(), bgImage.height.toDouble()),
  Offset.zero & size,
  paint,
);

给灭霸点色彩看看
运用ColorFilter.mode另一个用处便是简略的“修图”了,比方咱们能够将一张蓝天白云图修成夕阳西下的作用。

给灭霸点色彩看看

当然,转换为灰度图咱们也能够通过矩阵完成。

矩阵运算改动色彩

假如要想恣意互换色彩,那么运用矩阵运算更适宜。在 Flutter 中,ColorFilter.matrix 多增加了一行,这一行主要是在构建一些特殊的矩阵运算更便利,比方回转色的时分。

给灭霸点色彩看看

比方咱们要让改换后的图画完成回转:

  • 赤色色值=255-原赤色色值
  • 绿色色值=255-原绿色色值
  • 蓝色色值=255-原蓝色色值

那么构建如下矩阵就能够了。

给灭霸点色彩看看

因为最后一行数值对实践改变没影响,因而实践构建 ColorFilter.matrix 的时分,只需要传入20个参数就能够了。下面是运用了回转作用后的灭霸图,灭霸看起来像一个雕塑了。

给灭霸点色彩看看

下面咱们先来看一下运用矩阵完成五颜六色图变灰度图,用下面的矩阵就能完成,终究得到改换后的 R、G、B值是持平的,并且三个色值的系数相加等于1(确保数值不会超出255)。这个矩阵是官方提供的,实践上也是通过图画学研讨推导得到的。

给灭霸点色彩看看

对应灰度改换的 ColorFilter 的结构代码如下:

const greyScale = 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,
]);

最后,咱们来看看色彩循环改换的作用,色彩循环改换便是赤色部分变为原先像素的绿色值,绿色部分变到原先像素的蓝色值,然后蓝色部分变到原先像素的赤色值,对应的 ColorFilter 结构代码如下:

var colorRotation = ColorFilter.matrix(<double>[
  0, 1, 0, 0, 0,
  0, 0, 1, 0, 0,
  1, 0, 0, 0, 0,
  0, 0, 0, 1, 0
]);

有了这个咱们其实就能够做一些动效了,比方咱们把改变进程由动画值操控,得到下面的矩阵。

var colorRotation = ColorFilter.matrix(<double>[
  animationValue, 1-animationValue, 0, 0, 0,
  0, animationValue, 1-animationValue, 0, 0,
  1-animationValue, 0, animationValue, 0, 0,
  0, 0, 0, 1, 0
]);

咱们看看灭霸图片色彩改变的动画作用,整个画面的色彩在不断的改变,感觉像灭霸要开始“打响指”了。

给灭霸点色彩看看

ColorFilter 的运用

ColorFilter 的最佳运用场景应该是图片滤镜,咱们在图片类运用常常会看到各种滤镜作用(获得姓名都很好听,比方什么“纯洁”、“蓝调”,“怀旧”等等),实践上这种作用便是将一个色彩预置的改换矩阵运用到图片上。

总结

本篇介绍了色彩过滤器 ColorFilter 的运用以及原理,咱们绘图的时分能够运用 ColorFilter 处理图片,完成相似滤镜的作用。假如考虑简略运用,也能够直接运用 ColorFiltered 组件。


本篇源码已上传至:绘图相关源码,文件名为:color_filter_demo.dart

我是岛上码农,微信公众号同名,这是Flutter 入门与实战的专栏文章,提供体系化的 Flutter 学习文章。对应源码请看这儿:Flutter 入门与实战专栏源码。如有问题能够加自己微信沟通,微信号:island-coder

:觉得有收成请点个赞鼓励一下!

:收藏文章,便利回看哦!

:谈论沟通,相互进步!

我正在参加技能社区创作者签约方案招募活动,点击链接报名投稿。