• 初识滤镜


      说起滤镜,是图像处理中常用的工具,它将原图赋予各种效果,像是在原图是蒙上了一层有效果的镜子。虽然最终的效果是这样,但是在移动的设备上,其原理不可能是放两张图。而是对原图的每一个点的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

  • 相关阅读:
    hihocoder #1467 : 2-SAT·hihoCoder音乐节 2-SAT
    hihoCoder#1185 : 连通性·三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值
    hihoCoder1175 拓扑排序·二 拓扑排序
    012 列表的一些常用操作符
    011,列表2
    010 列表1
    009,分支和循环3
    008,分支和循环2
    006 Python的操作符
    005 Python的数值类型
  • 原文地址:https://www.cnblogs.com/fishbone-lsy/p/5246419.html
Copyright © 2020-2023  润新知