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