Android -- Camera2(Android5.0)

來源:互聯網
上載者:User

標籤:android   android開發   

Camera2

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

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

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

  • 全手動控制

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

  1. 感光度
  2. 手動對焦/AF開關
  3. AE/AF/AWB模式
  4. AE/AWB鎖
  5. 硬體視頻防抖
  6. 連續幀
乾貨

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為具體的裝置和模板和根據需要覆蓋的設定。

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

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

許可權
<uses-permission android:name="android.permission.CAMERA"/>
布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:orientation="vertical">    <TextureView        android:id="@+id/textureview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"/></LinearLayout>
核心代碼
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);    }}
我是天王蓋地虎的分割線

源碼:https://github.com/pinguo-yuyidong/Camera2

其他精彩文章文章

Android KSOAP2調用.net webservicejQuery教程(8)-DOM樹操作之使用反向插入方法android學習筆記(34)使用AlertDialog建立簡單對話方塊android學習筆記(33)畫廊視圖(Gallery)的功能和用法android navidgation drawer 在隱藏式瀏覽選單中如何改變List選中項的...

更多關於android開發文章


Android -- Camera2(Android5.0)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.