关于滤镜开发
<p>
本着兴趣与之前项目有一点小小涉及的原因,对移动端的滤镜相关开发有小小的研究,故将相关的内容整理出来,供大家一起交流。
首先我们要了解什么是滤镜?
滤镜最早出现在胶片相机时代,为了保护相机的传感器免受各种环境因素的影响,慢慢发展到后面则出现带各种效果的滤镜,我们常用的滤镜主要有9种,他们分别是:UV镜、偏振镜、中灰镜、中灰渐变镜、反向中灰渐变镜、彩色滤镜、近摄镜以及特殊效果滤镜。它们一般由玻璃(高端产品)、树脂和聚碳酸酯制成。
对于现在数字时代的图片,我们可以通过算法处理来达到以前镜片的效果,这个系列的文章就是对于整个移动端滤镜开发从0到1的过程。
对于滤镜相关开发,我相信大家第一印象就是在自定义View中ColorMatrix可以对图片进行一定的处理从而达到不同的效果,所以开篇就对ColorMatrix进行相关的介绍
一.矩阵
<p>
首先我们得了解矩阵这个概念及相关的运算
(1).定义
<p>
由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵。
(2).基本运算
二.Android颜色矩阵
<p>
Android中的颜色矩阵是用来表示三原色和透明度的4×5的矩阵
[ a, b, c, d, e,
f, g, h, i, j,
k, l, m, n, o,
p, q, r, s, t ]
颜色矩阵的功能划分如下
- a, b, c, d, e 表示三原色中的红色
- f, g, h, i, j 表示三原色中的绿色
- k, l, m, n, o 表示三原色中的蓝色
- p, q, r, s, t 表示颜色的透明度
- 第五列用于表示颜色的偏移量
一个颜色则使用[R, G, B, A]的方式进行表示,所以矩阵与颜色的计算方式则为
所以通过颜色矩阵我们会对原有的颜色进行改变
通过一个小的例子来实验一下
ColorMatrix colorMatrix = new ColorMatrix(new float[]{
0, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 1, 0,
});
canvas.drawBitmap(bitmap, null, new Rect(0, 0, getWidth()/2, getWidth()/2 * bitmap.getHeight() / bitmap.getWidth()), mPaint);
canvas.translate(getWidth()/2, 0);
mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
canvas.drawBitmap(bitmap, null, new Rect(0, 0, getWidth()/2, getWidth()/2 * bitmap.getHeight() / bitmap.getWidth()), mPaint);
可以看到这边我们设置的颜色矩阵是仅仅保留绿色通道的,所以通过计算得到新的颜色为[0,G,0,A]
接下来看看最后的效果
三.颜色处理运算方式
<p>
(1)setSaturation(设置饱和度)
<p>
色彩的饱和度调整其实是对颜色矩阵的第五列进行调整
/**
* 设置矩阵颜色的饱和度
*
* sat 0表示灰度、1表示本身
*/
public void setSaturation(float sat)
ColorMatrix提供的setSaturation函数是对RGB的饱和度都进行调整
其中: 参数float sat:表示把当前色彩饱和度放大的倍数。取值为0表示完全无色彩,即灰度图像(黑白图像);取值为1时,表示色彩不变动;当取值大于1时,显示色彩过度饱和
如图所示
(2)setScale (色彩缩放)
<p>
/**
* rScale 表示红色的数值的缩放比例
* gScale 表示绿色的数值的缩放比例
* bScale 表示蓝色的数值的缩放比例
* aScale 表示透明度的数值的缩放比例
*/
public void setScale(float rScale, float gScale, float bScale,float aScale)
ColorMatrix的缩放方法,其实就是根据矩阵的运算规则,对R、G、B、A的数值分别进行缩放操作
像上面的最开始举的例子其实就是对色彩进行缩放,设置的是单色道的缩放
// 绿色通道
mColorMatrix.setScale(0,1,0,1);
当然也可以对每个色道进行修改
mColorMatrix.setScale(1.2f,1.5f,1.1f,1);
如图所示
(3)setRotate (色彩旋转)
<p>
/**
* 用于色调的旋转运算
* axis=0 表示色调围绕红色进行旋转
* axis=1 表示色调围绕绿色进行旋转
* axis=2 表示色调围绕蓝色进行旋转
*/
public void setRotate(int axis, float degrees)
1)围绕红色轴旋转
我们可以根据三原色来建立一个三维向量坐标系,当围绕红色旋转时,我们将红色虚化为一个点,绿色为横坐标,蓝色为纵坐标,旋转θ°。
根据平行四边形法则R、G、B、A各值计算结果:
mColorMatrix.setRotate(0,90);
2)围绕绿色轴旋转
绿色虚化为一个点,蓝色为横坐标轴,红色为纵坐标轴,旋转θ°。
根据平行四边形法则R、G、B、A各值计算结果:
mColorMatrix.setRotate(1,90);
3)围绕蓝色轴旋转
蓝色虚化为一个点,红色为横坐标轴,绿色为纵坐标轴,旋转θ°。
根据平行四边形法则R、G、B、A各值计算结果:
mColorMatrix.setRotate(2,90);
写在后面的话
<p>
其实这一篇的ColorMatrix和我们整个的滤镜开发并没有太多的关联,所以这边也就简单的介绍一下了,毕竟用ColorMatrix来实现滤镜效果不能照顾到视频和相机相关,并且对于相对较复杂的滤镜也确实无能为力,所以后面会介绍更加给力的方法来实现滤镜效果,peace~~