前言

        在Android中需要通过graphics类来显示2D图形,在Graphics中包括了Canvas(画布)、Paint(画笔)、Color(颜色)、Bitmap(图像)等常用的类。Paint在自定义控件用的极其多,通过使用Paint可以根据你的想法画出各种各样的图案。


滤镜效果

对图像进行一定的过滤加工处理。使用Paint设置滤镜效果。

1.Alpha滤镜处理

MaskFilter

    (1)模糊遮罩滤镜(BlurMaskFilter)

    (2)浮雕遮罩滤镜(EmbossMaskFilter)

2.颜色RGB的滤镜处理

ColorMatrix

    (1)ColorMatrixColorFilter:色彩矩阵的颜色顾虑器。
    (2)LightingColorFilter:过滤颜色和增强色彩的方法。(光照颜色过滤器)
    (3)PorterDuffColorFilter:图形混合滤镜(图形学的一个理论飞跃)滤镜的所有处理效果都是通过颜色矩阵的变换实现的。


Part 1、Alpha滤镜处理

(1)模糊遮罩滤镜(BlurMaskFilter)

/**
         * radius:模糊的半径
         * style:
         * BlurMaskFilter.Blur.NORMAL
         * BlurMaskFilter.Blur.INNER
         * BlurMaskFilter.Blur.OUTER
         * BlurMaskFilter.Blur.SOLID
         */
        paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
        canvas.drawBitmap(mBitmap, 0, 0, paint);


效果~

android Paint实现模糊 手机painter模糊工具在哪里_android Paint实现模糊

注意在绘制图像的时候要关闭硬件加速,否则没有任何效果

setLayerType(View.LAYER_TYPE_SOFTWARE, null);


(2)浮雕遮罩滤镜(EmbossMaskFilter)

/**
         * direction, 指定长度为xxx的数组标量[x,y,z],用来指定光源的位置
         * ambient, 指定周边背景光源(0~1)
         * specular, 指镜面反射系数
         * blurRadius 指定模糊半径
         */
        paint.setMaskFilter(new EmbossMaskFilter(new float[]{30, 30, 30}, 1f, 60, 80));
        canvas.drawBitmap(mBitmap, 400f, 0f, paint);


效果~

android Paint实现模糊 手机painter模糊工具在哪里_滤镜_02


Part 2、颜色RGB的滤镜处理

(1)ColorMatrixColorFilter:色彩矩阵的颜色顾虑器

paint.setColorFilter(new ColorMatrixColorFilter(matrix));

这里颜色的变化是由matrix来决定的,该Matrix为5*5的矩阵

android Paint实现模糊 手机painter模糊工具在哪里_滤镜效果_03

的第一行参数abcde决定了图像的红色成分,第二行参数fghij决定了图像的绿色成分,第三行参数klmno决定了图像的蓝色成分,第四行参数pqrst决定了图像的透明度,第五列参数ejot是颜色的偏移量。

下面来说一下常见的矩阵

反相效果

ColorMatrix matrix = new ColorMatrix(new float[]{
                -1, 0, 0, 0, 255,
                0, -1, 0, 0, 255,
                0, 0, -1, 0, 255,
                0, 0, 0, 1, 0,
        });

颜色增强(可以起到变亮的效果)

ColorMatrix matrix = new ColorMatrix(new float[]{
                1.2f, 0, 0, 0, 0,
                0, 1.2f, 0, 0, 0,
                0, 0, 1.2f, 0, 0,
                0, 0, 0, 1.2f, 0,
        });


效果~

android Paint实现模糊 手机painter模糊工具在哪里_滤镜_04

黑白效果

ColorMatrix matrix = 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, 1f, 0,
        });


效果~

android Paint实现模糊 手机painter模糊工具在哪里_android Paint实现模糊_05

 去色的原理:只要将RGB三个通道的信息设置成一样的,即R=G=B,那图像就会变成了灰色,并且为了保证图像的亮度不变,同一个通道的R+G+B=1,如0.213+0.715+0.072=1;RGB=0.213, 0.715, 0.072; 三个数字是根据色彩光波频率及色彩心理学计算出来的。当然你也可以直接调用ColorMatrix的方法来设置

//饱和度设置(1,是原来不变;0灰色;>1增加饱和度)
        matrix.setSaturation(10);

复古效果

ColorMatrix matrix = 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, 1f, 0,
        });


效果~

android Paint实现模糊 手机painter模糊工具在哪里_android Paint实现模糊_06

你也可以通过缩放、旋转、平移来实现颜色的变化

ColorMatrix matrix = new ColorMatrix();
        matrix.setScale(1, 1, 1.4f, 1);
        //饱和度设置(1,是原来不变;0灰色;>1增加饱和度)
        matrix.setSaturation(10);
        /**
         * axis,代表绕哪一个轴旋转,0,1,2
         * 	(0红色轴,1绿色,2蓝色)
         * degrees:旋转的度数
         */
        matrix.setRotate(0, 30);
        //设置颜色过滤器
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));

(2)LightingColorFilter:过滤颜色和增强色彩的方法

/**
         * mul,multiply相乘 ---缩放
         * add,相加---平移
         */
        paint.setColorFilter(new LightingColorFilter(0x00ff00, 0xff0000));


效果~

android Paint实现模糊 手机painter模糊工具在哪里_android Paint实现模糊_07

(3)PorterDuffColorFilter:图形混合滤镜

要学习PorterDuffColorFilter就不得不了解下PorterDuff.Mode的属性

private static final Xfermode[] sModes = {
            /** [0, 0] */
            new PorterDuffXfermode(PorterDuff.Mode.CLEAR),//在该区域里什么都不显示 
            /** [Sa, Sc] */
            new PorterDuffXfermode(PorterDuff.Mode.SRC),//在该区域里只显示原图  
            /** [Da, Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.DST),//在该区域里只显示目标图  
            /** [Da, Sc * Da + (1 - Sa) * Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),//在该区域显示目标图并且相交部分显示原图  
            /** [Sa, Sa * Dc + Sc * (1 - Da)] */
            new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),//在该区域显示原图并且相交部分显示目标图  
            /** [Sa * Da, Sc * Da] */
            new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),//在该区域只显示相交区域且显示相交部分的原图  
            /** [Sa * Da, Sa * Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.DST_IN),//在该区域只显示相交区域且显示相交部分的目标图  
            /** [Sa * Da, Sc * Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),//在该区域只显示相交区域且显示两种的叠加颜色  
            /** [Sa * (1 - Da), Sc * (1 - Da)] */
            new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),//在该区域显示非相交部分的原图  
            /** [Da * (1 - Sa), Dc * (1 - Sa)] */
            new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),//在该区域显示非相交部分的目标图  

            /** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),//在该区域全部显示且原图在目标图的上方  
            /** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
            new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),//在该区域全部显示且目标图在原图的上方  
            /** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.XOR),//在该区域全部显示并且相交部分显示透明 
            /** [Sa + Da - Sa*Da,Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
            new PorterDuffXfermode(PorterDuff.Mode.DARKEN),//在该区域全部显示且相交部分的颜色变深  
            /** [Sa + Da - Sa*Da,Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
            new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),//在该区域全部显示且相交部分的颜色变亮  
            /** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
            new PorterDuffXfermode(PorterDuff.Mode.SCREEN),//在该区域全部显示且相交部分滤掉原图的颜色
            /** Saturate(S + D) */
            new PorterDuffXfermode(PorterDuff.Mode.ADD),//在该区域全部显示且相交部分饱和度相加  
            new PorterDuffXfermode(PorterDuff.Mode.OVERLAY)//在该区域全部显示且相交部分为叠加的颜色  
    };

接下来使用PorterDuffColorFilter来实现圆形图片(上篇是使用的是渲染器Shader)

android Paint实现模糊 手机painter模糊工具在哪里_滤镜效果_08

关键代码

@Override
protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);//屏蔽掉父类的onDraw方法
        Bitmap blank = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas drawCanvas = new Canvas(blank);
        drawCanvas.drawBitmap(ivBitmap, 0, 0, circlePaint);
        mode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
        circlePaint.setXfermode(mode);
        drawCanvas.drawBitmap(CircleBit, 0, 0, circlePaint);
        circlePaint.setXfermode(null);
}