说起滤镜,是图像处理中常用的工具,它将原图赋予各种效果,像是在原图是蒙上了一层有效果的镜子。虽然最终的效果是这样,但是在移动的设备上,其原理不可能是放两张图。而是对原图的每一个点的ARGB进行变换。所以在写代码之前,我们需要了解,图像的ARGB是如何进行变换的。Android中可以通过颜色矩阵(ColorMatrix类)进行颜色变换。

 

  

 

  通过上面的计算方式一目了然了。图片本身的每个点的颜色是C矩阵,我们的滤镜矩阵则是A矩阵,最后经过滤镜处理得到的图上的每个点是R矩阵。

  在此,列一个将图片滤为黑白的为例  

                            Paint paint = new Paint();
                            ColorMatrix colorMatrix = new ColorMatrix();
                            colorMatrix.set(new float[] {
                                    0.3f, 0.59f, 0.11f, 0, 0,
                                    0.3f, 0.59f, 0.11f, 0, 0,
                                    0.3f, 0.59f, 0.11f, 0, 0,
                                    0, 0, 0, 1, 0 });
                            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));

 

  经这样的矩阵变换后,新的图片RGB三个值是相等的,大小只取决于0.3*R+0.59*G+0.11*B的值。这样图片就变成了黑白的。

  在自己学习的demo中,我用了一个SurfaceView来显示处理后的图片。  

public class FilterSurfaceView extends SurfaceView {

    SurfaceHolder surfaceHolder;
    boolean backThreadLock = true;
    boolean threadIsRunning = true;
    String pathStr;

    public FilterSurfaceView(Context context) {
        super(context);
        init();
    }

    public FilterSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public FilterSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init(){
        surfaceHolder = this.getHolder();
        surfaceHolder.addCallback(callback);
    }
    
    // 将pathStr目录下的指定文件进行滤镜处理,并显示处理后的bitmap
    private class FiltBitmapTask extends AsyncTask<Void , Integer , Bitmap>{

        @Override
        protected Bitmap doInBackground(Void... params) {
            // 用于关闭线程
            while (threadIsRunning){
                if (!backThreadLock && pathStr != null && !TextUtils.isEmpty(pathStr)){
                    Canvas cv = null;

                    Bitmap bitmap = BitmapFactory.decodeFile(pathStr);

                    try {
                        synchronized (surfaceHolder){

                            cv = surfaceHolder.lockCanvas();
                            Paint paint = new Paint();
                            ColorMatrix colorMatrix = new ColorMatrix();
                            // 黑白滤镜矩阵
                            colorMatrix.set(new float[] {
                                    0.3f, 0.59f, 0.11f, 0, 0,
                                    0.3f, 0.59f, 0.11f, 0, 0,
                                    0.3f, 0.59f, 0.11f, 0, 0,
                                    0, 0, 0, 1, 0 });
                            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
                            // 图简单只取了屏幕宽高
                            RectF rectF = new RectF(0 , 0 , ScreenHelper.getInstance().getScreenWidth()
                                    , ScreenHelper.getInstance().getScreenHeight());
                            cv.drawBitmap(bitmap, null, rectF, paint);
                            surfaceHolder.unlockCanvasAndPost(cv);
                        }
                    }catch (Exception e){

                    }finally {
                        backThreadLock = true;
                        if (!bitmap.isRecycled()){
                            bitmap.recycle();
                            bitmap = null;
                        }
                    }
                }
                return null;
            }
            return null;
        }

    }

    public void setPathStr(String pathStr){
        this.pathStr = pathStr;
    }


    SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            FiltBitmapTask filtBitmapTask = new FiltBitmapTask();
            filtBitmapTask.execute();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            threadIsRunning = false;
        }
    };

    public void refresh(){
        backThreadLock = false;
    }


}

 

  

 

 

Done

 

posted on 2016-03-06 00:45  Fishbonell  阅读(197)  评论(0编辑  收藏  举报