zoukankan      html  css  js  c++  java
  • 初识滤镜

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

  • 相关阅读:
    MVC5管道处理模型
    http协议下:为什么请求与响应会做到准确误的对应。不会出现请求与响应的错乱
    修改 IIS 队列长度
    修改 ASP.NET 请求队列的限制
    Windows性能查看器:系统的性能信息(I/O,IIS最大连接数,Sql) ,以及解决 asp.net IIS 一二百多用户并发
    详解 ASP.NET异步
    [C#]获得线程池中活动的线程数
    一个http请求就是一个线程吗,java的服务是每收到一个请求就新开一个线程来处理吗
    IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的...
    ASP.NET MVC 线程和并发
  • 原文地址:https://www.cnblogs.com/fishbone-lsy/p/5246419.html
Copyright © 2011-2022 走看看