返回

相机预览 - Android Camera2 API入门指南

Android

引言

相机是现代智能手机必不可少的组件之一。随着Android平台的发展,Android对相机API的支持也越来越完善。在Android 5.0中,谷歌推出了Camera2 API,该API提供了更加强大的相机控制功能,并支持RAW格式图像输出。本文将通过一个简单的例子,介绍如何使用Camera2 API实现相机预览。

配置权限

在Android 6.0以后的版本中,需要在清单文件中申明使用相机的权限。

<uses-permission android:name="android.permission.CAMERA" />

布局文件

本文的布局文件非常简单,只有一个TextureView。TextureView是一种特殊的View,它可以直接显示来自Camera2 API的图像数据。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextureView
        android:id="@+id/texture_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

实现预览

在实现具体编码之前,先简单介绍下相关的几个重要的类:

  • CameraManager:相机管理类,可以用来遍历相机列表、打开相机等。
  • CameraCharacteristics:相机特征类,包含了相机的各种特性信息,如分辨率、对焦模式等。
  • CameraDevice:相机设备类,用于控制相机设备。
  • CaptureRequest:捕获请求类,用于向相机设备发送捕获请求。
  • CaptureResult:捕获结果类,用于接收相机设备的捕获结果。

现在,让我们来一步步实现相机预览:

  1. 获取CameraManager实例。
  2. 遍历相机列表,选择要使用的相机。
  3. 获取相机的CameraCharacteristics。
  4. 创建一个用于预览的CaptureRequest。
  5. 创建一个TextureView.SurfaceTextureListener,并在TextureView的SurfaceTexture准备好时,创建CameraDevice并开始预览。
private void startPreview() {
    // 获取CameraManager实例
    CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

    // 遍历相机列表,选择要使用的相机
    String cameraId = null;
    for (String id : cameraManager.getCameraIdList()) {
        CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id);
        // 选择前置摄像头
        if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
            cameraId = id;
            break;
        }
    }

    // 获取相机的CameraCharacteristics
    CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);

    // 创建一个用于预览的CaptureRequest
    CaptureRequest.Builder previewRequestBuilder = cameraManager.createCaptureRequest(cameraId, CameraDevice.TEMPLATE_PREVIEW);

    // 创建一个TextureView.SurfaceTextureListener
    TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
            // 创建CameraDevice并开始预览
            try {
                cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
                    @Override
                    public void onOpened(CameraDevice cameraDevice) {
                        // 将TextureView的SurfaceTexture作为预览Surface
                        previewRequestBuilder.addTarget(surfaceTexture);

                        // 创建CameraCaptureSession
                        cameraDevice.createCaptureSession(Arrays.asList(surfaceTexture), new CameraCaptureSession.StateCallback() {
                            @Override
                            public void onConfigured(CameraCaptureSession session) {
                                // 开始预览
                                session.setRepeatingRequest(previewRequestBuilder.build(), null, null);
                            }

                            @Override
                            public void onConfigureFailed(CameraCaptureSession session) {

                            }
                        }, null);
                    }

                    @Override
                    public void onDisconnected(CameraDevice cameraDevice) {

                    }

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

                    }
                }, null);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

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

        }

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

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

        }
    };

    // 设置TextureView的SurfaceTextureListener
    textureView.setSurfaceTextureListener(surfaceTextureListener);
}

结束语

本文介绍了如何在Android中使用Camera2 API实现相机预览。Camera2 API提供了更加强大的相机控制功能,并支持RAW格式图像输出。希望本文能够帮助您更好地理解和使用Camera2 API。