当前位置: 代码迷 >> Android >> zxing源码分析(1)camera部分
  详细解决方案

zxing源码分析(1)camera部分

热度:78   发布时间:2016-04-27 23:41:29.0
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的核心方法的作用。