美文网首页
移动端滤镜开发(一)ColorMatrix实现滤镜效果

移动端滤镜开发(一)ColorMatrix实现滤镜效果

作者: 前世小书童 | 来源:发表于2016-11-08 19:09 被阅读1113次

    关于滤镜开发

    <p>
    本着兴趣与之前项目有一点小小涉及的原因,对移动端的滤镜相关开发有小小的研究,故将相关的内容整理出来,供大家一起交流。

    首先我们要了解什么是滤镜?

    滤镜最早出现在胶片相机时代,为了保护相机的传感器免受各种环境因素的影响,慢慢发展到后面则出现带各种效果的滤镜,我们常用的滤镜主要有9种,他们分别是:UV镜、偏振镜、中灰镜、中灰渐变镜、反向中灰渐变镜、彩色滤镜、近摄镜以及特殊效果滤镜。它们一般由玻璃(高端产品)、树脂和聚碳酸酯制成。

    对于现在数字时代的图片,我们可以通过算法处理来达到以前镜片的效果,这个系列的文章就是对于整个移动端滤镜开发从0到1的过程。

    对于滤镜相关开发,我相信大家第一印象就是在自定义View中ColorMatrix可以对图片进行一定的处理从而达到不同的效果,所以开篇就对ColorMatrix进行相关的介绍

    一.矩阵

    <p>

    首先我们得了解矩阵这个概念及相关的运算

    (1).定义

    <p>
    由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵。

    图1 矩阵
    (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~~

    相关文章

      网友评论

          本文标题:移动端滤镜开发(一)ColorMatrix实现滤镜效果

          本文链接:https://www.haomeiwen.com/subject/bulzettx.html