zoukankan      html  css  js  c++  java
  • 二维码zxing源码分析(一)camera部分

    首先,我们先把zxing的源代码给下载下来,这个网上有很多,我下载的是2.3的,不得不说这个谷歌提供的包包含的功能还是很全面的。

        我把下载的包解压后,找到android文件夹,导入到ecplise中,我们来分析一下,里面的架构
        一、book,如果查询的结果是图书信息,用户可以选择查询该书的进一步详细信息,该包,包含了搜索与展示书籍的相关类。
        二、camera/camera.open 这个一个关于摄像头的类,核心类是CameraManager
        三、clipboard 剪贴板
        四、encode:编码功能的各个组件集合,核心类为QRCodeEncoder,最终实施编码的是MultiFormatWriter类
        五、history:扫描历史管理,核心类是HistoryManager
        六、result: 条形码扫描的结果被分为不同的类型,所有的类型,都定义在com.google.zxing.client.result.ParsedResultType中,对于不同的类型都有对应的处理方法;xxxResultHandler,所有的ResultHandler都包含在此包中。不同的xxxResultHandler还提供了扫描结果页面要展示几个button,每个button的文本及需要绑定的事件等等
       
       我们先从相机的源码部分开始分析,因为我只会用到扫描和输出结果部分,其它的部分将会去掉
          相机部分一共有六个类,分别是
          OpenCameraInterface :打开相机类
          CameraConfigurationManager:相机配置类
          CameraManager:  核心类,相机管理类    
          AutoFocusManager:暂时没有看
          FrontLightMode:枚举
          PreviewCallback:预览回调类
    一、OpenCameraInterface,这是一个摄像头打开的类,里面的方法为open(),即打开摄像头,我注释了一下
    public static Camera open() {
        // 获取摄像头的数量
        int numCameras = Camera.getNumberOfCameras();
        //如果没有找到相机则退出
        if (numCameras == 0) {
          Log.w(TAG, "No cameras!");
          return null;
        }
    
        
        int index = 0;
        while (index < numCameras) {
          //初始化相机信息类
          Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
          //获取相机的信息
          Camera.getCameraInfo(index, cameraInfo);
          //判断是否是后置摄像头
          if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
            break;
          }
          index++;
        }
        
        //打开相机
        Camera camera;
        if (index < numCameras) {
          Log.i(TAG, "Opening camera #" + index);
          camera = Camera.open(index);
        } else {
          Log.i(TAG, "No camera facing back; returning camera #0");
          camera = Camera.open(0);
        }
    
        return camera;
      }

        从这个方法中把摄像头打开

         二、CameraConfigurationManager摄像头配置类,在这个类中主要是配置了预览分辨率、闪光灯和焦点等参数
           下面的方法主要有 initFromCameraParameters(),通过调findBestPreviewSizeValue方法,来获取最佳的相机预览分辨率
      void initFromCameraParameters(Camera camera) {
        //获取相机的参数
        Camera.Parameters parameters = camera.getParameters();
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        //构造一个点
        Point theScreenResolution = new Point();
         //给点进行赋值,屏幕的宽和高 Resolution分辨率的意思
        display.getSize(theScreenResolution);
        screenResolution = theScreenResolution;
        Log.i(TAG, "Screen resolution: " + screenResolution);
        cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);
        Log.i(TAG, "Camera resolution: " + cameraResolution);
      }
       setDesiredCameraParameters() 方法,设置相机的闪光灯和焦点等参数
       findBestPreviewSizeValue() 方法,去除掉不合适的分辨率,来选择最佳的分辨率
     三、CameraManager是整个摄像头的核心类,另外几个类都是在这个类中调用的,用它来对相机的初始化和参数进行统一的管理
           openDriver方法()
     
    public synchronized void openDriver(SurfaceHolder holder) throws IOException {
        Camera theCamera = camera;
        if (theCamera == null) {
          theCamera = OpenCameraInterface.open();
          if (theCamera == null) {
            throw new IOException();
          }
          camera = theCamera;
        }
        //设置摄像头预览功能
        theCamera.setPreviewDisplay(holder);
    
        //初始化执行的操作
        if (!initialized) {
          initialized = true;
          //初始化相机的参数,选择最佳的预览分辨率
          configManager.initFromCameraParameters(theCamera);
          if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {
            setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight);
            requestedFramingRectWidth = 0;
            requestedFramingRectHeight = 0;
          }
        }
    
        Camera.Parameters parameters = theCamera.getParameters();
        String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save these, temporarily
        try {
          //设置必要的参数,包括焦点,闪光灯等
          configManager.setDesiredCameraParameters(theCamera, false);
        } catch (RuntimeException re) {
          // Driver failed
          Log.w(TAG, "Camera rejected parameters. Setting only minimal safe-mode parameters");
          Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
          // Reset:
          if (parametersFlattened != null) {
            parameters = theCamera.getParameters();
            parameters.unflatten(parametersFlattened);
            try {
              theCamera.setParameters(parameters);
              configManager.setDesiredCameraParameters(theCamera, true);
            } catch (RuntimeException re2) {
              // Well, darn. Give up
              Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration");
            }
          }
        }
    
      }
    以上这些都是Camera的核心方法,我们可以看到,程序是通过调用CaptureActivity来实现运行的,在CaptureActivity中调用了Camera的一些方法,在CaptureActivity中通过initCamera(surfaceHolder);这个方法,开始扫描,最后得到扫描的结果。而布局文件中
    <SurfaceView android:id="@+id/preview_view"
                   android:layout_width="fill_parent"
                   android:layout_height="fill_parent"/>
     
      <com.google.zxing.client.android.ViewfinderView
          android:id="@+id/viewfinder_view"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:visibility="gone" />
    一个是预览的窗口,一个是用来自定义显示的扫描的窗口。到此,就总结完了,基本上弄懂了它是怎么运行的,以及Camera的核心方法的作用。
     
     
                                                                             
         
     
  • 相关阅读:
    json学习系列(1)-使用json所要用到的jar包下载
    Java 时间架构图
    时间纪元与时区介绍
    HTML5 Canvas 绘制库存变化折线
    HTML5 Canvas 笛卡尔坐标系转换尝试
    像孩童一样欣喜的看着自己的成长
    《老炮儿》结尾貌似历史上的一幕
    很多人还在守着金饭碗要饭
    还是用文本编辑器编程让人愉悦
    Node.js 网页爬虫再进阶,cheerio助力
  • 原文地址:https://www.cnblogs.com/zhangjin055/p/4692609.html
Copyright © 2011-2022 走看看