Android實戰技巧之三十三:android.hardware.camera2使用指南,

來源:互聯網
上載者:User

Android實戰技巧之三十三:android.hardware.camera2使用指南,

API 21中將原來的camera API棄用轉而推薦使用新增的camera2 API,這是一個大的動作,因為新API換了架構,讓開發人員用起來更難了。
先來看看camera2包架構:

這裡引用了管道的概念將安卓裝置和網路攝影機之間聯通起來,系統向網路攝影機發送Capture請求,而網路攝影機會返回CameraMetadata。這一切建立在一個叫作CameraCaptureSession的會話中。

下面是camera2包中的主要類:

其中CameraManager是那個站在高處統管所有攝像投裝置(CameraDevice)的管理者,而每個CameraDevice自己會負責建立CameraCaptureSession以及建立CaptureRequest。CameraCharacteristics是CameraDevice的屬性描述類,非要做個對比的話,那麼它與原來的CameraInfo有相似性。
類圖中有著三個重要的callback,雖然這增加了閱讀代碼的難度,但是你必須要習慣,因為這是新包的風格。其中CameraCaptureSession.CaptureCallback將處理預覽和拍照圖片的工作,需要重點對待。

這些類是如何相互配合的?下面是簡單的流程圖。

我是用SurfaceView作為顯示對象(當然還可以TextureView去顯示,詳見參考中的項目)
核心代碼如下:

        mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);        mSurfaceView = (SurfaceView)findViewById(R.id.surfaceview);        mSurfaceHolder = mSurfaceView.getHolder();        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {            @Override            public void surfaceCreated(SurfaceHolder holder) {                initCameraAndPreview();            }        });
    private void initCameraAndPreview() {        Log.d("linc","init camera and preview");        HandlerThread handlerThread = new HandlerThread("Camera2");        handlerThread.start();        mHandler = new Handler(handlerThread.getLooper());        try {            mCameraId = ""+CameraCharacteristics.LENS_FACING_FRONT;            mImageReader = ImageReader.newInstance(mSurfaceView.getWidth(), mSurfaceView.getHeight(),                    ImageFormat.JPEG,/*maxImages*/7);            mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mHandler);            mCameraManager.openCamera(mCameraId, DeviceStateCallback, mHandler);        } catch (CameraAccessException e) {            Log.e("linc", "open camera failed." + e.getMessage());        }    }
private CameraDevice.StateCallback DeviceStateCallback = new CameraDevice.StateCallback() {        @Override        public void onOpened(CameraDevice camera) {            Log.d("linc","DeviceStateCallback:camera was opend.");            mCameraOpenCloseLock.release();            mCameraDevice = camera;            try {                createCameraCaptureSession();            } catch (CameraAccessException e) {                e.printStackTrace();            }        }    };
    private void createCameraCaptureSession() throws CameraAccessException {        Log.d("linc","createCameraCaptureSession");        mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);        mPreviewBuilder.addTarget(mSurfaceHolder.getSurface());        mState = STATE_PREVIEW;        mCameraDevice.createCaptureSession(                Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()),                mSessionPreviewStateCallback, mHandler);    }
private CameraCaptureSession.StateCallback mSessionPreviewStateCallback = new            CameraCaptureSession.StateCallback() {        @Override        public void onConfigured(CameraCaptureSession session) {            Log.d("linc","mSessionPreviewStateCallback onConfigured");            mSession = session;            try {                mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);                mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);                session.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);            } catch (CameraAccessException e) {                e.printStackTrace();                Log.e("linc","set preview builder failed."+e.getMessage());            }        }    };
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback =            new CameraCaptureSession.CaptureCallback() {        @Override        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,                                       TotalCaptureResult result) {//            Log.d("linc","mSessionCaptureCallback, onCaptureCompleted");            mSession = session;            checkState(result);        }        @Override        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,                                        CaptureResult partialResult) {            Log.d("linc","mSessionCaptureCallback, onCaptureProgressed");            mSession = session;            checkState(partialResult);        }        private void checkState(CaptureResult result) {            switch (mState) {                case STATE_PREVIEW:                    // NOTHING                    break;                case STATE_WAITING_CAPTURE:                    int afState = result.get(CaptureResult.CONTROL_AF_STATE);                    if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||                            CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState                            || CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState                            || CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED == afState) {                        //do something like save picture                    }                    break;            }        }    };

按下capture按鈕:

    public void onCapture(View view) {        try {            Log.i("linc", "take picture");            mState = STATE_WAITING_CAPTURE;            mSession.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);        } catch (CameraAccessException e) {            e.printStackTrace();        }    }

測試用genemotion模擬器,直接調用筆記本的網路攝影機。
配置圖如下:

demo介面如:

源碼:
請參考github中的兩個demo項目:
https://github.com/pinguo-yuyidong/Camera2
https://github.com/googlesamples/android-Camera2Basic

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.