使用camera2 实现相机预览
时间: 2023-05-25 09:02:36 浏览: 206
使用Camera2 Api实现相机预览需要以下步骤:
1. 实现CameraDevice.StateCallback接口,当相机设备状态发生变化时会回调该接口。
2. 获取相机管理器,并申请相机权限。
3. 打开相机,并设置预览Surface和相机回调。
4. 获取预览数据,进行相应的渲染和处理。
以下是示例代码:
```java
public class CameraPreviewActivity extends AppCompatActivity implements
SurfaceHolder.Callback, CameraDevice.StateCallback {
private CameraManager mCameraManager;
private String mCameraId;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCaptureSession;
private SurfaceHolder mSurfaceHolder;
private Size mPreviewSize;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_preview);
SurfaceView surfaceView = findViewById(R.id.surface_view);
mSurfaceHolder = surfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
mCameraId = mCameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
} else {
openCamera();
}
}
private void openCamera() {
try {
mCameraManager.openCamera(mCameraId, this, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
try {
List<Surface> surfaces = new ArrayList<>();
// 设置预览Surface
Surface previewSurface = mSurfaceHolder.getSurface();
surfaces.add(previewSurface);
// 创建相机会话
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
mCaptureSession = session;
startPreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Log.e("CameraPreview", "createCaptureSession failed");
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startPreview() {
try {
// 创建预览请求
CaptureRequest.Builder previewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewBuilder.addTarget(mSurfaceHolder.getSurface());
//设置自动对焦模式
previewBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 开始预览
mCaptureSession.setRepeatingRequest(previewBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// 获取预览大小
try {
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(mCameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mPreviewSize = map.getOutputSizes(SurfaceHolder.class)[0];
// 更新Surface大小
int rotatedPreviewWidth = width;
int rotatedPreviewHeight = height;
int maxWidth = mSurfaceHolder.getSurfaceFrame().width();
int maxHeight = mSurfaceHolder.getSurfaceFrame().height();
if (maxWidth > 0 && maxHeight > 0) {
rotatedPreviewWidth = Math.min(maxWidth, maxHeight);
rotatedPreviewHeight = Math.max(maxWidth, maxHeight);
}
mSurfaceHolder.setFixedSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCameraDevice.close();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 1) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera();
} else {
Toast.makeText(this, "Camera permission not granted", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onDisconnected(CameraDevice camera) {
mCameraDevice.close();
}
@Override
public void onError(CameraDevice camera, int error) {
mCameraDevice.close();
mCameraDevice = null;
}
}
```
在AndroidManifest.xml中添加相机权限:
```xml
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
```
在布局文件中添加SurfaceView:
```xml
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```