你的位置:首页 > 操作系统

[操作系统]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的核心方法的作用。