感謝強者我朋友霸氣資訊支援手機一枚XD,不然光搞視訊鏡頭都不知道要搞多久了啊...
Camera2 API在21版本時新增,它能夠利用多線程去接收需求和反應,跟以往的Camera相比效能差了一大截,不過能接影像的僅有SurfaceView和TextureView
下圖是對岸牛人畫的流程圖,個人認為對不管剛入門還是老手都非常易懂的圖啊
首先啟動執行序
設定好Surface
取得及設定CameraID,CameraID為0(CaptureRequest.LENS_FACING_BACK)或1(CaptureRequest.LENS_FACING_FRONT)
設定好ImageReader,ImageReader用於讀取影像資料的類別
接著開啟相機會觸發CameraDevice.StateCallback該事件內會有方法可以知道相機開啟是否正常
正常情況必須建立Session並透過setRepeatingRequest不斷的請求相機傳送影像,並且可以透過CameraCaptureSession.CaptureCallback來得知擷取影像進度及完成時的事件
以上大概是整體的程序,太久沒寫Android有錯請前輩們多多指教
Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.cyfang.testcamera.MainActivity" > <SurfaceView android:id="@+id/surfaceView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" /> </RelativeLayout>
Manifest:
<uses-permission android:name="android.permission.CAMERA" />
Code:
package com.cyfang.testcamera; import java.util.Arrays; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.graphics.ImageFormat; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCaptureSession.CaptureCallback; import android.hardware.camera2.CameraCaptureSession.StateCallback; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.hardware.camera2.TotalCaptureResult; import android.media.ImageReader; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; @SuppressLint("NewApi") public class MainActivity extends Activity { private SurfaceView surfaceView; private SurfaceHolder holder; private CameraManager manager; private CaptureRequest.Builder builder; private CameraDevice cameraDevice; private HandlerThread handlerThread; private Handler handler; private ImageReader imageReader; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); // 取得Holder holder = surfaceView.getHolder(); // 設定預覽大小 holder.setFixedSize(1280, 960); // 設定事件 holder.addCallback(surfaceCallback); } private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { if (cameraDevice != null) { cameraDevice.close(); } } @Override public void surfaceCreated(SurfaceHolder holder) { handlerThread = new HandlerThread("HT"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); // 創建影像物件 imageReader = ImageReader.newInstance(1280, 960, ImageFormat.RGB_565, 3); try { // 取得相機鏡頭清單,可用於判斷該相機是否具備雙鏡頭或是單鏡頭 // manager.getCameraIdList() // 開啟相機 // 0是後面鏡頭 = CaptureRequest.LENS_FACING_BACK // 1是前置鏡頭 = CaptureRequest.LENS_FACING_FRONT manager.openCamera("0", DeviceStateCallback, handler); } catch (CameraAccessException e) { Log.e("CameraAccessException", e.getMessage()); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }; // 相機裝置狀態 private CameraDevice.StateCallback DeviceStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { try { cameraDevice = camera; // 設定預覽模式 builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); // 將影像設定置SurfaceView builder.addTarget(holder.getSurface()); // 建立影像傳輸 cameraDevice.createCaptureSession(Arrays.asList(holder.getSurface(), imageReader.getSurface()), CameraCaptureCallback, handler); } catch (CameraAccessException e) { Log.e("CameraAccessException", e.getMessage()); } } @Override public void onDisconnected(CameraDevice camera) { } @Override public void onError(CameraDevice camera, int error) { } }; // 相機擷取中及完成的事件 private CameraCaptureSession.CaptureCallback CameracaptureCallback = new CaptureCallback() { @Override public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { } @Override public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) { } }; // 相機擷取狀態 private CameraCaptureSession.StateCallback CameraCaptureCallback = new StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { try { session.setRepeatingRequest(builder.build(), CameracaptureCallback, handler); } catch (CameraAccessException e) { Log.e("CameraAccessException", e.getMessage()); } } @Override public void onConfigureFailed(CameraCaptureSession session) { } }; }
執行結果:
圖片來源:
http://wiki.jikexueyuan.com/project/android-actual-combat-skills/images/33-3.png