目录

  1. 颜色和滤镜的基本知识

  2. 实践:通过ColorFilter实现颜色颜色调节

  3. 实践:图片滤镜(黑白、冷暖色)

  4. 遇到的问题

  5. 资料

  6. 收获

一、颜色和滤镜的基本知识

我们是如何看到图不同颜色的?

图片来源:[播放器色觉辅助功能开发,助力提升色觉障碍用户的视频观看体验]

不同波长的光具有不同的颜色,在我们可见光范围内蓝色光波长是短波,长波长的光呈现红色。
我们人类有三种不同的视锥细胞,它们对不同的光有不同的敏感度,由于不同人的视锥细胞,也造成了世界上有4%-6%的色弱或者色盲者。

图片来源:[播放器色觉辅助功能开发,助力提升色觉障碍用户的视频观看体验]

我们这篇学习的滤镜,对于视觉有障碍的人群可以起到视觉校正的作用。同时对于视觉正常的人群,也可以通过滤镜使色彩发生变化,适合不同的场景,比如,哀悼日模式,在或者应用更广的短视频或者直播中的美颜、滤镜等功能,增加一些趣味性。

了解背景后,下面我们从颜色的三个要素来一起学习下颜色。
颜色三要素:色调(色相)、饱和度、亮度

色调是区别各种不同色彩的最准确的标准,任何黑白灰以外的颜色都有色相的属性,而色相也就是由原色、间色和复色来构成的。
根据色环的色彩排列,相邻色相混合,饱和度基本不变(如红黄相混合所得的橙色)。对比色相混合,最易降低饱和度,以至成为灰暗色彩
亮度不仅决定物体照明程度,而且决定物体表面的反射系数。如果我们看到的光线来源于光源,那么亮度决定于光源的强度。如果我们看到的是来源于物体表面反射的光线,那么亮度决定于照明的光源的强度和物体表面的反射系数。
来自 颜色三要素百科

图片来自:[色环百科]

在android中有ColorMatrix颜色矩阵工具类,帮我们封装实现了颜色的三要素的调节以及不同矩阵相乘的实现。

色调

public void setRotate(int axis, float degrees) {
reset();
double radians = degrees * Math.PI / 180d;
float cosine = (float) Math.cos(radians);
float sine = (float) Math.sin(radians);
switch (axis) {
// Rotation around the red color
case 0:
mArray[6] = mArray[12] = cosine;
mArray[7] = sine;
mArray[11] = -sine;
break;
// Rotation around the green color
case 1:
mArray[0] = mArray[12] = cosine;
mArray[2] = -sine;
mArray[10] = sine;
break;
// Rotation around the blue color
case 2:
mArray[0] = mArray[6] = cosine;
mArray[1] = sine;
mArray[5] = -sine;
break;
default:
throw new RuntimeException();
}
}

我们可以看到色调的调节有两个参数,参数axis代表 围绕哪种颜色进行旋转,degress是指旋转的角度。范围是【-180度,180度】
比如下面这个矩阵就是axis为红色时的结果。

饱和度
饱和度(saturation)色彩的鲜艳程度

public void setSaturation(float sat) {
reset();
float[] m = mArray;
final float invSat = 1 - sat;
final float R = 0.213f * invSat;
final float G = 0.715f * invSat;
final float B = 0.072f * invSat;
m[0] = R + sat; m[1] = G; m[2] = B;
m[5] = R; m[6] = G + sat; m[7] = B;
m[10] = R; m[11] = G; m[12] = B + sat;
}

参数sat的代表饱和度的强弱。范围是【0,1】
例如,当sat为0时,RGB对应的值为0.213f,0.715f,0.072f,这是就可以实现黑白模式

亮度

public void setScale(float rScale, float gScale, float bScale,
float aScale) {
final float[] a = mArray;
for (int i = 19; i > 0; --i) {
a[i] = 0;
}
a[0] = rScale;
a[6] = gScale;
a[12] = bScale;
a[18] = aScale;
}

四个参数分别代表rgba四个通道的的范围,范围区间在【0,1】。

通过上面的介绍,我们了解到可以通过修改颜色的三要素实现滤镜的功能。下面开启我们的实践。

二、实践:ColorFilter对View进行换色

我们先通过颜色矩阵设置固定的值来对普通图片的颜色修改,实现黑白、暖色、冷色三种变化,然后在通过动态的调整色调、饱和度、以及亮度进行实现图片的颜色调节。下面开启我们这一小节的旅程。

首先我们可以直接给View的Bitamp设置ColorFilter,来实现颜色的变化

//黑白模式 Gray=R*0.3+G*0.59+B*0.11
float[] mBWMatrix = {
0.3f,0.59f,0.11f,0,0,
0.3f,0.59f,0.11f,0,0,
0.3f,0.59f,0.11f,0,0,
0,0,0,1,0};
//暖色调的处理可以增加红绿通道的值
float[] mWarmMatrix = {
2,0,0,0,0<