Android Camera1小結

1.概述

本文將仿照此前博文Android NDK Camera2小結的方式,來記錄Camera1的使用。

Camera1僅爲Java實現(不必糾結於此,Native實現...JNI反調...你懂的~且性能差別不大)。

本文的講解基於UML Component圖,描述Camera1核心對象及API的調用生成關係。如縮略圖不清晰,可點擊放大。

Component圖中,模塊爲函數,節點爲對象。橫向(左或右)箭頭爲資源釋放操作調用。調用過程與順序/時機無關。

其中綠色模塊爲Camera對象成員方法,黃色爲Camera類靜態方法。

粉色爲Camera.Parameters對象成員方法。

紅色爲自定義方法,需要自行實現。

Component圖未包含所有接口,僅爲Camera1預覽模式的簡單實現。

2.Camera1的使用

相比於Camera2的複雜架構,Camera1(android.hardware.Camera)十分簡單,僅爲一個類文件。因此,操作也即爲簡便。

遵循以下步驟便可完成預覽。

2.1獲取Camera數量

使用靜態方法Camera.getNumberOfCameras,獲取camera數量num。Camera ID範圍爲【0,num-1】。

int cameraCount = Camera.getNumberOfCameras();

2.2獲取CameraInfo

以Camera ID作爲傳參,調用靜態方法Camera.getCameraInfo,獲取對應CameraInfo。CameraInfo僅包括三項,Facing(鏡頭方向,前置/後置),orientation(鏡頭旋轉角度)和canDisableShutterSound(是否支持取消快門聲音)。

通常通過CameraInfo,來確定要使用的Camera。

for (int i = 0; i < cameraCount; i++) {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(i, cameraInfo);
}

2.3開啓Camera

以Camera ID作爲傳參,調用靜態方法Camera.open即可打開設備,該方法將返回一個Camera對象。但打開設備,並不代表能夠看到畫面。仍需要後續操作,來完成預覽。包括設置Camera.Parameters,以及畫布(surface View)。若需要使用圖片數據,則需要設置Callback接口。

Camera camera = Camera.open(cameraId);

2.4設置Camera配置參數

獲取Camera對象後,調用成員方法getParameters,可以獲取Camera.Parameters。Camera.Parameters中包含的信息,要遠多於CameraInfo。在獲取Camera.Parameters後,可以調用成員方法getSupportedXXXX來獲取相應的數據。例如分辨率,預覽格式等。

對於分辨率,可以調用Camera.Parameters成員方法getSupportedPreviewSizes,獲取List<Camera.Size>。設置則是調用Camera.Parameters成員方法setPreviewSize。

Camera.Parameters params = camera.getParameters();
List<Camera.Size> supportSizes = params.getSupportedPreviewSizes();
...
mParams.setPreviewSize(width, height);

對於預覽格式,可以調用Camera.Parameters成員方法getSupportedPreviewFormats,獲取List<Integer>。設置則是調用setPreviewFormat。由於前端爲視頻流,因此,通常使用PixelFormat.YCbCr_420_SP。

parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP);

當然,還有其它一些參數可以設置,例如曝光補償(可參照關於Android Camera的曝光補償),焦距(可參照關於Android Camera變焦)等。

List<Integer> zoomRatios =parameters.getZoomRatios();
int MAX_ZOOM = mParams.getMaxZoom();
int tMaxExposure=parameters.getMaxExposureCompensation();
int tMinExposure=parameters.getMinExposureCompensation();
...
mParams.setZoom(currentZoom);
parameters.setExposureCompensation(mExposureCompensationRate);

在設置完Camera.Parameters子項後,需要將其回填給Camera,需要調用Camera成員方法setParameters。

mCamera.setParameters(mParams);

2.5設置預覽界面

surface view爲Camera的畫布,僅需將其SurfaceHolder作爲傳參,調用Camera的成員方法setPreviewDisplay即可完成預覽界面設置。

SurfaceHolder holder;
...
mCamera.setPreviewDisplay(holder);

2.6預覽畫面矯正

通過用Camera的成員方法setDisplayOrientation調設置畫面的矯正角度,使得畫面以自然0度顯示在畫布上。通常使用角度爲0,90,180,270。關於android設備的角度問題,將另闢博文描述。

mCamera.setDisplayOrientation(90);

2.7設置previewCallback

如果想獲取圖像數據,則需要通過調用Camera的成員方法setPreviewCallback添加Callback方法。默認返回爲YCbCr_420_SP格式的數據。

PreviewCallback mpreview = new PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera camera) {

        }
    };
mCamera.setPreviewCallback(mpreview);
    public interface PreviewCallback
    {
        /**
         * Called as preview frames are displayed.  This callback is invoked
         * on the event thread {@link #open(int)} was called from.
         *
         * <p>If using the {@link android.graphics.ImageFormat#YV12} format,
         * refer to the equations in {@link Camera.Parameters#setPreviewFormat}
         * for the arrangement of the pixel data in the preview callback
         * buffers.
         *
         * @param data the contents of the preview frame in the format defined
         *  by {@link android.graphics.ImageFormat}, which can be queried
         *  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.
         *  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}
         *             is never called, the default will be the YCbCr_420_SP
         *             (NV21) format.
         * @param camera the Camera service object.
         */
        void onPreviewFrame(byte[] data, Camera camera);
    };

2.8啓動預覽

完成相關設置後,僅需調用Camera成員方法startPreview即可。

mCamera.startPreview();

2.9停止預覽

調用Camera成員方法stopPreview即可。

mCamera.stopPreview()

2.10關閉相機

調用Camera成員方法release即可。

mCamera.release();

3.結束語

Android Camera2 Java實現始於andorid 5.0, Native 實現則開始於android7.0(API level24)。

到目前爲止,5.0以上系統市場佔有率爲85%,7.0以上系統僅爲37%,因此,Camera2不足以適配所有Android 設備。

所以,Camera1雖然最終將被替代,但仍有存在價值。Camera1僅爲單個類,沒有Camera2複雜的結構,並且java實現還是相對簡單實用。在不考慮被遺棄的情況,Camera1還是更爲通用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章