滤镜效果

滤镜效果大家肯定都知道,毕竟现在相机这么牛,一般都有这个功能。
不废话,开搞!

所谓滤镜效果,就是对一张图像的颜色进行特定处理(ARGB)

准备工作

创建一个继承于View的类,然后

//写3个私有成员变量
private Paint paint;//用于原图的画笔
private Paint paint2;//用于滤镜的画笔
private Bitmap bitmap;//图像

//在构造函数中初始化一下
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.shuaige);

接下来的操作将都在onDraw中进行,并且要关闭硬件加速先

setLayerType(View.LAYER_TYPE_SOFTWARE,null);

原图

滤镜效果_第1张图片
shuaige.jpg

首先在onDraw中把原图画出来

//画出原图
canvas.drawBitmap(bitmap,50,50,paint);
//画板位置向下平移
canvas.translate(0,500);

1、Alpha滤镜处理

Alpha滤镜效果主要通过MaskFilter类进行处理,MaskFilter拥有两个子类BlurMaskFilter和EmbossMaskFilter,BlurMaskFilter用来绘制模糊阴影,EmbossMaskFilter用来用来实现浮雕立体效果

(1)BlurMaskFilter

首先看一下BlurMaskFilter的构造方法

/**
* @param radius 阴影的半径
* @param style  
*               NORMOL -- 整个图像都被模糊掉
*               SOLID -- 图像边界外产生一层与Paint颜色一致阴影效果,不影响图像的本身
*               OUTER -- 图像边界外产生一层阴影,并且将图像变成透明效果
*               INNER -- 在图像内部边沿产生模糊效果
*/
BlurMaskFilter(float radius, Blur style)

接下来看看它们的效果

● style---NORMOL

paint2.setMaskFilter(new BlurMaskFilter(60, BlurMaskFilter.Blur.NORMAL));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第2张图片
QQ截图20170830211237.png

● style---SOLID

paint2.setMaskFilter(new BlurMaskFilter(60, BlurMaskFilter.Blur.NORMAL));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第3张图片
QQ截图20170830213038.png

● style---OUTER

paint2.setMaskFilter(new BlurMaskFilter(60, BlurMaskFilter.Blur.NORMAL));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第4张图片
QQ截图20170830213251.png

● style---INNER

paint2.setMaskFilter(new BlurMaskFilter(60, BlurMaskFilter.Blur.NORMAL));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第5张图片
QQ截图20170830213443.png

(2)EmbossMaskFilter

首先看一下EmbossMaskFilter的构造方法

/**
* @param direction  指定光源的位置,长度为xxx的数组标量[x,y,z]
* @param ambient    环境光的因子 (0~1),越接近0,环境光越暗
* @param specular   镜面反射系数 越接近0,镜面反射越强
* @param blurRadius 模糊半径 值越大,模糊效果越明显
*/
EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)

接下来看看它们的效果

new float[]{2,2,2}, 0.1f, 10, 60

paint2.setMaskFilter(new EmbossMaskFilter(new float[]{2,2,2},0.1f,10,60));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第6张图片
QQ截图20170830214650.png

2、颜色RGB的滤镜处理

首先需要大家掌握一些矩阵运算的基本知识(这个大家有点线性代数基础的都会懂的)--乘法


滤镜效果_第7张图片
举证乘法.png

再看一下颜色矩阵乘法


颜色矩阵乘法.gif

该矩阵意思就是将图中颜色(RGBA)透明度变成它原来的一半,但是我们会发现,这种算法只能乘,如果我们有相加的需求,这种明显是不适用的。所以,应该在四阶色彩变换矩阵上增加一个“哑元坐标”,来实现所列的矩阵运算。
哑元坐标.gif

(1)ColorMatrix

颜色RGB的滤镜处理主要通过ColorMatrix这个颜色矩阵类来完成,下面一起来看看具体代码和显示

● 平移运算---加法(就是将某个颜色值增加一个固定的值,此处是将绿色的值加了100)

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                1, 0,0,0,0,
                0,1,0,0,100,
                0,0,1,0,0,
                0,0,0,1,0
        });
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第8张图片
QQ截图20170830223456.png

● 反相效果 -- 底片效果(就是将每个像素都变成它的相反的值)

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                -1, 0,0,0,255,
                0,-1,0,0,255,
                0,0,-1,0,255,
                0,0,0,1,0
        });
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第9张图片
QQ截图20170830224810.png

● 缩放运算---乘法 -- 颜色增强(此处将每个色值都乘1.4倍)

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                1.4f, 0,0,0,0,
                0,1.4f,0,0,0,
                0,0,1.4f,0,0,
                0,0,0,1,0
        });

//或者
//ColorMatrix colorMartrix = new ColorMatrix();
//colorMartrix.setScale(1.2f,1.2f,1.2f,1);

paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第10张图片
QQ截图20170830225334.png

● 黑白照片

去色原理:只要把R G B 三通道的色彩信息设置成一样,那么图像就会变成灰色,同时为了保证图像亮度不变,同一个通道里的R+G+B =1。

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                0.213f, 0.715f,0.072f,0,0,
                0.213f, 0.715f,0.072f,0,0,
                0.213f, 0.715f,0.072f,0,0,
                0,0,0,1,0
        });
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第11张图片
QQ截图20170830225729.png

● 发色效果---(比如红色和绿色交换)

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                0,1,0,0,0,
                1, 0,0,0,0,
                0,0,1,0,0,
                0,0,0,1,0
        });
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第12张图片
QQ截图20170830230034.png

● 复古效果

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                1/2f,1/2f,1/2f,0,0,
                1/3f, 1/3f,1/3f,0,0,
                1/4f,1/4f,1/4f,0,0,
                0,0,0,1,0
        });
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第13张图片
QQ截图20170830230303.png

● 颜色通道过滤(此处过滤红色)

ColorMatrix colorMartrix = new ColorMatrix(new float[]{
                1, 0,0,0,0,
                0,0,0,0,0,
                0,0,0,0,0,
                0,0,0,1,0
        });
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第14张图片
QQ截图20170830230630.png

● 增加饱和度

ColorMatrix colorMartrix = new ColorMatrix();
colorMartrix.setSaturation(2f);
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第15张图片
QQ截图20170830231845.png

● 颜色旋转

ColorMatrix colorMartrix = new ColorMatrix();
//setRotate参数
//aixs-- 0 红色轴,1,绿色,2,蓝色
//degrees -- 旋转的角度
colorMartrix.setRotate(0,10f);
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第16张图片
QQ截图20170830232406.png

● 颜色矩阵叠加效果(红色值加100,另外再各个颜色增强)

ColorMatrix colorMartrix1 = new ColorMatrix(new float[]{
                1, 0,0,0,100,
                0,1,0,0,0,
                0,0,1,0,0,
                0,0,0,1,0
        });
 ColorMatrix colorMartrix2 = new ColorMatrix(new float[]{
                1.4f, 0,0,0,0,
                0,1.4f,0,0,0,
                0,0,1.4f,0,0,
                0,0,0,1.4f,0
        });
colorMartrix.setConcat(colorMartrix1,colorMartrix2);
paint2.setColorFilter(new ColorMatrixColorFilter(colorMartrix));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第17张图片
QQ截图20170830233123.png

(2)LightingColorFilter

LightingColorFilter主要是可以对颜色值一次性的进行乘和加,但是这里只是修改RGB值,首先看一看LightingColorFilter的构造方法。

/**
*mul   颜色值乘的倍数
*add   颜色值增加的值
*/
LightingColorFilter(int mul, int add)

下面看看具体应用

//表示将原有的颜色值先乘0x00ff00,再加0xff0000
paint2.setColorFilter(new LightingColorFilter(0x00ff00,0xff0000));
canvas.drawBitmap(bitmap,50,150,paint2)
滤镜效果_第18张图片
QQ截图20170830235335.png

(3)PorterDuffColorFilter

PorterDuffColorFilter可以用于颜色与原图像混合叠加的效果
首先开看一看PorterDuffColorFilter的构造方法

/**
*color 进行叠加的颜色
*mode 叠加的模式
*/
PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode)

再来看看叠加模式PorterDuff.Mode有哪些

public enum Mode {
        /** [0, 0] */
        CLEAR       (0),
        /** [Sa, Sc] */
        SRC         (1),
        /** [Da, Dc] */
        DST         (2),
        /** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
        SRC_OVER    (3),
        /** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
        DST_OVER    (4),
        /** [Sa * Da, Sc * Da] */
        SRC_IN      (5),
        /** [Sa * Da, Sa * Dc] */
        DST_IN      (6),
        /** [Sa * (1 - Da), Sc * (1 - Da)] */
        SRC_OUT     (7),
        /** [Da * (1 - Sa), Dc * (1 - Sa)] */
        DST_OUT     (8),
        /** [Da, Sc * Da + (1 - Sa) * Dc] */
        SRC_ATOP    (9),
        /** [Sa, Sa * Dc + Sc * (1 - Da)] */
        DST_ATOP    (10),
        /** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
        XOR         (11),
        /** [Sa + Da - Sa*Da,
             Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
        DARKEN      (16),
        /** [Sa + Da - Sa*Da,
             Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
        LIGHTEN     (17),
        /** [Sa * Da, Sc * Dc] */
        MULTIPLY    (13),
        /** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
        SCREEN      (14),
        /** Saturate(S + D) */
        ADD         (12),
        OVERLAY     (15);

        Mode(int nativeInt) {
            this.nativeInt = nativeInt;
        }

        /**
         * @hide
         */
        public final int nativeInt;
    }

这里一共有17种叠加模式,接下来我将以蓝色为叠加颜色,然后展示所有叠加效果。

这里需要注意 这里我们的bitmap属于目标图片(DST),Color.argb(175,140,90,200)属于源图片(SRC)
再来看看叠加规则
[] : [展示的透明度, 展示的颜色值]
Sa:源图片的透明度
Sc:源图片的颜色值
Da:目标图片的透明度
Dc:目标图片的颜色值

● CLEAR

paint2.setColorFilter(new PorterDuffColorFilter(Color.argb(175,140,90,200), PorterDuff.Mode.CLEAR));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第19张图片
CLEAR 效果
混合算法:[0, 0]

● SRC

paint2.setColorFilter(new PorterDuffColorFilter(Color.argb(175,140,90,200), PorterDuff.Mode.SRC));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第20张图片
SRC 效果
混合算法:[Sa, Sc]

● DST

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.DST));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第21张图片
DST 效果
混合算法:[Da, Dc]

● SRC_OVER

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_OVER));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第22张图片
SRC_OVER 效果
混合算法:[Sa + (1 - Sa)Da, Rc = Sc + (1 - Sa)Dc]

● DST_OVER

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.CLEAR));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第23张图片
DST_OVER 效果
混合算法:[Sa + (1 - Sa)Da, Rc = Dc + (1 - Da)Sc]

● SRC_IN

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第24张图片
SRC_IN 效果
混合算法:[Sa * Da, Sc * Da]

● DST_IN

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.DST_IN));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第25张图片
DST_IN 效果
混合算法:[Sa * Da, Sa * Dc]

● SRC_OUT

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_OUT));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第26张图片
SRC_OUT效果
混合算法:[Sa * (1 - Da), Sc * (1 - Da)]

● DST_OUT

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.DST_OUT));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第27张图片
DST_OUT 效果
混合算法:[Da * (1 - Sa), Dc * (1 - Sa)]

含义参考 SRC_OUT

● DST_ATOP

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.DST_ATOP));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第28张图片
DST_ATOP 效果
混合算法:[Sa, Sa * Dc + Sc * (1 - Da)]

● SRC_ATOP

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.CLEAR));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第29张图片
SRC_ATOP 效果
混合算法:[Da, Sc * Da + (1 - Sa) * Dc]

● XOR

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.XOR));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第30张图片
XOR 效果
混合算法:[Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]

● DARKEN

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.DARKEN));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第31张图片
DARKEN 效果
混合算法:[Sa + Da - SaDa,Sc(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]

● LIGHTEN

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.LIGHTEN));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第32张图片
LIGHTEN 效果
混合算法:[Sa + Da - SaDa, Sc(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]

● MULTIPLY

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.MULTIPLY));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第33张图片
MULTIPLY 效果
混合算法:[Sa * Da, Sc * Dc]

● SCREEN

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SCREEN));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第34张图片
SCREEN 效果
混合算法:[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]

● ADD

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.ADD));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第35张图片
ADD 效果
混合算法:Saturate(S + D)

● OVERLAY

paint2.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.OVERLAY));
canvas.drawBitmap(bitmap,50,150,paint2);
滤镜效果_第36张图片
OVERLAY 效果
混合算法:

个人觉得很全了,差不多可以满足大部分滤镜效果

版权声明:个人原创,若转载,请注明出处

你可能感兴趣的:(滤镜效果)