二維碼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的核心方法的作用。
 
 
                                                                         
     
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM