Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android -- Camera2(Android5.0)

Android -- Camera2(Android5.0)

編輯:關於Android編程

Android -- Camera2(Android5.0)

 

Camera2

Camera2是Android5.0中的其中一個新的特性,新的API。與原來的camera API相比,不同之處在於:

原生支持RAW照片輸出突發拍攝模式

制約拍照速度的不再是軟件而是硬件。以Nexus 5為例,分辨率全開下Andorid L的連拍速度可達到30fps。

全手動控制

快門、感光度、對焦、測光、硬件視頻防抖等多種參數都被整合到了新的API內。新的API中添加的手動控制功能列表:

感光度手動對焦/AF開關AE/AF/AWB模式AE/AWB鎖硬件視頻防抖連續幀

干貨

Camera2 程序邏輯與原Camera有很大不同。

CameraManager,系統服務,通過 CameraManager去獲得camera設備對象。CameraDevices提供描述相機硬件設備支持可用的和輸出的參數,這些信息通過 CameraCharacteristics獲得,CameraCharacteristics又是從 getCameraCharacteristics(cameraId)獲得,通過freamwork中的源碼發現,其實這裡就是直接調用的Camera API接口。

通過camera拍照,應用首先要創建由相機設備的輸出surface組成的拍照會話,createCaptureSession(List, CameraCaptureSession.StateCallback, Handler)。每個surface必須預先設置適當的大小和格式去匹配相機設備的可支持的大小和格式。一個目標surface可以從不同的類中獲取,包括SurfaceView,SurfaceTexture via Surface(SurfaceTexture), MediaCodec, MediaRecorder, Allocation, and ImageReader.

一旦請求被建立,他可以交給活動的拍照會話:一次拍照(one-shot )或者無止境連續拍照或預覽(Repeating)。兩種方法都有一個其他的方式:接受一系列的請求作為burst拍照/重復burst。

public void openCamera (String cameraId, CameraDevice.StateCallback callback, Handler handler)

使用getCameraIdList()來獲得可用攝像設備的列表。一旦成功打開相機,CameraDevice.StateCallback中的onOpened(CameraDevice)將被調用。相機設備可以通過調用createCaptureSession()和createCaptureRequest()去設置操作。如果打開相機設備失敗,那麼設備回調的onError方法將被調用,和後續調用相機設備將拋出一個CameraAccessException。

public abstract CaptureRequest.Builder createCaptureRequest (int templateType)

為請求拍照創建一個CaptureRequest.Builder,初始化目標用例的模板。選擇最好的設置為特定的相機設備,所以不建議為不同的相機設備重用相同的請求,創建一個builder為具體的設備和模板和根據需要覆蓋的設置。

11

public abstract void createCaptureSession (List outputs, CameraCaptureSession.StateCallback callback, Handler handler)

活動著的會話決定了相機的output Surfaces 為每個拍照的要求。給定請求可以使用全部或只有部分的output Surfaces。一旦CameraCaptureSession創建,可以提交capture請求、captureBurst請求,setRepeatingRequest請求或setRepeatingBurst請求。

 

權限

布局

 



    

 

核心代碼

 
public class CameraFragment extends Fragment implements TextureView.SurfaceTextureListener {

    private TextureView mPreviewView;
    private Handler mHandler;
    private HandlerThread mThreadHandler;
    private Size mPreviewSize;
    private CaptureRequest.Builder mPreviewBuilder;

    public static CameraFragment newInstance() {
        return new CameraFragment();
    }

    @SuppressWarnings(ResourceType)
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.camera_frag, null);
        initLooper();
        initUIAndListener(v);
        return v;
    }
    //很多過程都變成了異步的了,所以這裡需要一個子線程的looper
    private void initLooper() {
        mThreadHandler = new HandlerThread(CAMERA2);
        mThreadHandler.start();
        mHandler = new Handler(mThreadHandler.getLooper());
    }
    //可以通過TextureView或者SurfaceView
    private void initUIAndListener(View v) {
        mPreviewView = (TextureView) v.findViewById(R.id.textureview);
        mPreviewView.setSurfaceTextureListener(this);
    }

    @SuppressWarnings(ResourceType)
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        try {
            //獲得CameraManager
            CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
            //獲得屬性
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(0);
            //支持的STREAM CONFIGURATION
            StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            //顯示的size
            mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
            //打開相機
            cameraManager.openCamera(0, mCameraDeviceStateCallback, mHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    //TextureView.SurfaceTextureListener
    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(CameraDevice camera) {
            try {
                startPreview(camera);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDisconnected(CameraDevice camera) {

        }

        @Override
        public void onError(CameraDevice camera, int error) {

        }
    };
    //開始預覽,主要是camera.createCaptureSession這段代碼很重要,創建會話
    private void startPreview(CameraDevice camera) throws CameraAccessException {
        SurfaceTexture texture = mPreviewView.getSurfaceTexture();
        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        Surface surface = new Surface(texture);
        try {
            mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        mPreviewBuilder.addTarget(surface);
        camera.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, mHandler);
    }

    private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {

        @Override
        public void onConfigured(CameraCaptureSession session) {
            try {
                updatePreview(session);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(CameraCaptureSession session) {

        }
    };

    private void updatePreview(CameraCaptureSession session) throws CameraAccessException {
        session.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
    }
}
 

 


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved