最近在看关于自定义控件的东西,顺便看到了关于滤镜的东西,就写出来分享一下

这个有三个已知子类,写一个滤镜效果,只需要第一个已知子类就够用了,这个类构造方法public ColorMatrixColorFilter (ColorMatrix matrix),ColorMatrix的初始化则需要一个4*5的fload行的矩阵 大家看下面就知道了



这是我的写法



这个就是颜色矩阵,修改这里面的值就可以做到滤镜的效果,先改一下试试,看运行结果

对了 首先要给画笔设置上一个颜色

mpaint.setColor(Color.argb(255, 255, 128, 103));
,然后看效果


这个解释绘制出来的效果,然后改一改,再看效果

ColorMatrix colorMatrix = new ColorMatrix(new float[]{        0.9F, 1, 0, 0, 0,  //A        0, 0.5F, 0.6f, 0, 0,  //R        0, 0, 0.5F, 0, 0.7f,  //G        0, 0, 0, 1, 0,     //B});
随便改了改


这就是效果


换一张图片可能效果更加明显

 原图

运行代码后的图



还有这样



是不是很酷炫?

然而刚才的矩阵怎么计算的,下面是他的公式


矩阵ColorMatrix的一行乘以矩阵MyColor的一列作为矩阵Result的一行,这里MyColor的RGBA值我们需要转换为[0, 1]。那么我们依据此公式来计算下我们得到的RGBA值是否跟我们计算得出来的圆的RGBA值一样:

就是这样。

下面是这个控件的源码,只需要在里面填上一个方法,就可以做一个滤镜了。 全部项目的源码在我的 GitHub 上。。。

package com.liran.custom_view.MyView;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ColorMatrix;import android.graphics.ColorMatrixColorFilter;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.View;import com.liran.custom_view.R;import com.liran.custom_view.Utils.DisplayUtil;import com.liran.custom_view.Utils.MeasureUtil;/** * Created by lr 李冉 on 2015-08-31. */public class CustomView extends View {    private String TAG = "CustomView";    private Paint mpaint;    private int radious = 50;    private int x, y;// 位图绘制时左上角的起点坐标    private Bitmap bitmap;    public CustomView(Context context) {        super(context);        initPaint(context);    }    public CustomView(Context context, AttributeSet attrs) {        super(context, attrs);        initPaint(context);    }    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initPaint(context);    }    private void initPaint(Context context) {        mpaint = new Paint();        mpaint.setAntiAlias(true);        /*         * 设置画笔样式为描边,圆环嘛……当然不能填充不然就么意思了         *         * 画笔样式分三种:         * 1.Paint.Style.STROKE:描边         * 2.Paint.Style.FILL_AND_STROKE:描边并填充         * 3.Paint.Style.FILL:填充         *///        mpaint.setStyle(Paint.Style.STROKE);        mpaint.setStyle(Paint.Style.FILL);        // 设置画笔颜色为自定义颜色        mpaint.setColor(Color.argb(255, 255, 128, 103));        //设置颜色矩阵  注意 是 4x5的float[]类型的矩阵   修改这里的数值就相当于做一个滤镜了        ColorMatrix colorMatrix = new ColorMatrix(new float[]{                0.9F, 0, 0.5f, 0, 0,  //A                0, 0.5F, 0, 0.6f, 0,  //R                0, 0, 0.5F, 0.3f, 0,  //G                0, 0, 0, 1, 0,     //B        });        // 设置颜色过滤        mpaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));        // 设置颜色过滤//        mpaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000));        // 设置颜色过滤//        mpaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN));        /*         * 设置描边的粗细,单位:像素px         * 注意:当setStrokeWidth(0)的时候描边宽度并不为0而是只占一个像素        */        mpaint.setStrokeWidth(10);        initRes(context);    }    private void initRes(Context context) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bg2);       /* x = Math.abs(getMeasuredWidth() / 2 - bitmap.getWidth() / 2);        y = Math.abs(getMeasuredHeight() / 2 - bitmap.getHeight() / 2);*/        x = MeasureUtil.getScreenWidth(context)[0] / 2 - bitmap.getWidth() / 2 - 18;        y = (MeasureUtil.getScreenWidth(context)[1] - MeasureUtil.getStatusBarHeight(context) - DisplayUtil.dip2px(context, 50)) / 2 - bitmap.getHeight() / 2;        Log.d(TAG, "initRes x=" + x + "y=" + y + " MeasureUtil.getScreenWidth(context)[1]= " + MeasureUtil.getScreenWidth(context)[1]);        Log.d(TAG, "initRes bitmap.getHeight()=" + bitmap.getHeight());    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);//        Log.d(TAG, "onDraw   with="+getMeasuredWidth()+" heigh="+getMeasuredHeight());//        canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, radious, mpaint);        Log.d(TAG, "onDraw x=" + x + "  y= " + y);        canvas.drawBitmap(bitmap, x, y, mpaint);    }    public synchronized void setRadius(int radius) {        this.radious = radius;        invalidate();    }    /**     * 开启一个线程去执行动画     */    public void startAnmi() {        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                 /*                 * 确保线程不断执行不断刷新界面                 */                    while (true) {                        try {                        /*                         * 如果半径小于200则自加否则大于200后重置半径值以实现往复                         */                            if (radious <= 200) {                                radious += 10;                                //非主线程刷新view                                postInvalidate();                            } else {                                radious = 0;                            }                            // 每执行一次暂停40毫秒                            Thread.sleep(40);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                }            }        }).start();    }}




更多相关文章

  1. Android(安卓)Studio如何去掉丑陋的标题栏//values文件夹结构的
  2. Android中EditText光标在4.0中的bug及解决方法
  3. Android修改圆形进度条ProgressBar的默认颜色
  4. android ListView拖动时会黑屏的解决方法
  5. pc机进入android的shell
  6. matix in Android
  7. Android(安卓)自定义Spinner字体、颜色、大小
  8. Android(安卓)OpenGL添加光照和材料属性
  9. 猫猫学iOS之二维码学习,快速生成二维码

随机推荐

  1. 围绕原生与 H5 交互实践聊聊 Android(安
  2. Android系统字体加载流程
  3. Android之模仿微信登陆界面(一)
  4. Android ListView 最后一行分割线不显示
  5. android 使用include 调用内部组件
  6. 2014.01.07 ——— android开发实例之Qui
  7. 转化屏幕•ViewFlipper 的使用
  8. android 桌面文件夹ui美化
  9. 启动Android模拟器报错需安装Intel HAXM
  10. Android NDK JNI 入门笔记-day01-创建项