感謝強者我朋友霸氣資訊支援手機一枚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

