androidcamera2api使用详解

Android Camera2 API使用详解

前言

在 Android 开发中,使用相机是非常常见的操作之一。从 Android 5.0 开始,Google 推出了全新的 Camera2 API,相比老的 Camera API,Camera2 API 更加灵活,性能更高,功能更强大,尤其是支持 RAW 图片和 YUV 格式的输出,对于对照片、视频有要求的开发者非常适用。在此,我将为大家详细介绍 Android Camera2 API 的使用方法。

步骤

1. 获取相机管理器

首先,我们需要获取相机管理器的实例,用于管理我们的摄像头设备。相机管理器可以通过 getSystemService() 方法获取。

CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

2. 获取支持的相机列表

获取相机管理器实例之后,我们需要获取当前设备支持的相机列表。我们可以通过 getCameraIdList() 方法来获取相机列表。

String[] cameraIdList = cameraManager.getCameraIdList();

3. 获取相机设备

获取相机列表之后,我们需要从中选择一个相机设备来进行调用。我们可以通过 getCameraCharacteristics() 方法来获取指定相机设备的特性,这里选择了后置摄像头。

String cameraId = null;
CameraCharacteristics characteristics = null;

for (String id : cameraIdList) {
    CameraCharacteristics tempCharacteristics = cameraManager.getCameraCharacteristics(id);
    int cameraOrientation = tempCharacteristics.get(CameraCharacteristics.LENS_FACING);

    if (cameraOrientation == CameraCharacteristics.LENS_FACING_BACK) {
        characteristics = tempCharacteristics;
        cameraId = id;
        break;
    }
}

4. 获取相机输出尺寸

获取相机设备之后,我们需要确定相机输出的尺寸。在 Camera2 API 中,我们可以通过这样的方式获取相机输出尺寸:

StreamConfigurationMap streamConfigurationMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] outputSizes = streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888);

5. 创建预览请求和预览 surface

获取相机输出尺寸之后,我们需要创建一个预览请求和预览 Surface,来将相机的输出流传递给我们的 UI 界面。预览请求可以通过 createCaptureRequest() 方法创建,而预览 Surface 则可以通过 SurfaceHolder 或 SurfaceTexture 从我们的 UI 布局中获取。

SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
Surface previewSurface = new Surface(surfaceTexture);

CaptureRequest.Builder previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewBuilder.addTarget(previewSurface);

6. 启动预览

获取预览请求和 Surface 之后,我们需要启动相机预览,通过 setRepeatingRequest() 方法进行设置,这样就可以将相机的预览流显示在我们的 UI 界面上了。

cameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() {
    @Override
    public void onConfigured(@NonNull CameraCaptureSession session) {
        try {
            session.setRepeatingRequest(previewBuilder.build(), null, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConfigureFailed(@NonNull CameraCaptureSession session) {

    }
}, null);

7. 拍照

最后,我们可以通过 createCaptureRequest() 方法来创建一个拍照请求,并通过 CaptureCallback 监听器来获取拍照结果,并将拍摄的照片保存在指定目录。

CaptureRequest.Builder photoBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
photoBuilder.addTarget(photoSurface);

cameraCaptureSession.stopRepeating();
cameraCaptureSession.abortCaptures();

cameraCaptureSession.capture(photoBuilder.build(), null, new CameraCaptureSession.CaptureCallback() {
    @Override
    public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
        super.onCaptureCompleted(session, request, result);

        Image image = null;
        try {
            image = mImageReader.acquireLatestImage();
            if (image != null) {
                ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                byte[] data = new byte[buffer.remaining()];
                buffer.get(data);

                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

                File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera", "photo.jpg");
                FileOutputStream outputStream = new FileOutputStream(file);
                outputStream.write(data);
                outputStream.flush();
                outputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (image != null) {
                image.close();
            }
        }
    }
}, null);

后记

通过上面的步骤,我们就可以很容易地使用 Camera2 API 来实现相机的预览和拍照功能了。当然,这只是一个简单的示例,如果要实现更加丰富的功能,还需要更加深入地学习 Camera2 API 的使用方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:androidcamera2api使用详解 - Python技术站

(0)
上一篇 2023年3月29日
下一篇 2023年3月29日

相关文章

  • 解析C++中构造函数的默认参数和构造函数的重载

    解析C++中构造函数的默认参数和构造函数的重载攻略 构造函数的默认参数 在 C++ 中,可以给函数的形参设置默认参数。这个特性也适用于构造函数。在类定义中,可以为某个构造函数的参数提供默认值,这样在使用该构造函数时,可以不传递对应参数,直接使用默认值。 下面展示一个使用默认参数的构造函数示例: class Person { public: Person(in…

    other 2023年6月26日
    00
  • 8款超好用的svg编辑工具用起来

    以下是“8款超好用的SVG编辑工具”的完整攻略: 8款超好用的SVG编辑工具 SVG是一种矢量图形格式,它可以在不失真的情况下缩放到任意大小。本攻略将介绍8款超好用的编辑工具,帮助您轻松创建和编辑SVG图形。 1. Inkscape Inkscape是一款免费的开源SVG编辑器,它提供了丰富的绘图工具和编辑功能。Inkscape支持多种文件格式,包括SVG、…

    other 2023年5月7日
    00
  • mac版本cornerstone的无限期破解方法(转)

    Mac版本Cornerstone的无限期破解方法(转) Cornerstone是Mac OS X平台上的一款版本控制管理软件,为软件开发者提供了诸如代码库的浏览、文本比较、合并、历史记录查看和撤销等一系列工具。但是,这款软件并不是免费的,如果你需要使用所有的高级功能,你需要购买正版才能使用。那么,有没有无限期破解方法呢?本文将介绍一种可行的解决方案。 破解方…

    其他 2023年3月28日
    00
  • java根据子节点获取所有的父节点

    在Java中,如何根据子节点获取所有的父节点? 解决方案 以下是根据子节点获取所有父节点的解决方案: 方案1:使用递归 可以使用递归来实现根据子获取所有父节点的功能。具体步骤如下: 定义一个方法,该方法接收一个子节点作为参数。 在方法中首先获取子节点的父节点。 如果父节点不为空,则将父节点添加到一个列表中,并递归调用该方法,将父节点作为参数传递给该方法。 如…

    other 2023年5月7日
    00
  • iOS UIButton 点击无响应的解决办法

    为了解决iOS UIButton点击无响应的问题,可以采用以下几种方法: 1. 检查是否禁用了用户交互 UIButton默认是开启用户交互的,但是有时候可能会在代码中禁用完就忘记开启用户交互了。如果用户交互被禁用了,按钮是不会产生响应的。 解决办法: 在代码中查找是否有地方将按钮的用户交互禁用了,如果发现了这样的代码,需要移除或注释掉。可以通过以下方式检查哪…

    other 2023年6月27日
    00
  • ubuntu18.04安装frp的配置说明

    Ubuntu 18.04安装frp的配置说明 frp是一种高性能的反向代理工具,可以帮助我们将内网服务暴露到公网上。本攻略将介如何在Ubuntu 18.04上安装frp,并提供两个示例。 安装frp 以下是在Ubuntu 18.04上安frp的步骤: 下载frp。可以从frp的官方网站下载最新版本的frp,命令如下: wget https://github.…

    other 2023年5月9日
    00
  • datagridview中添加checkbox和常用处理方式.

    DataGridView中添加Checkbox和常用处理方式 DataGridView是.NET Framework中常用的控件之一,它可以用于显示和编辑数据。在DataGridView中添加Checkbox可以方便地进行多选操作。本文将详讲解如何在DataGridView中添加Checkbox以及常用的处理方式。 添加Checkbox 在DataGridV…

    other 2023年5月7日
    00
  • lumion材质系统室内渲染6.3

    Lumion材质系统室内渲染6.3 Lumion是一款专业的实时渲染软件,已经被广泛应用于建筑、室内设计、景观设计等领域。Lumion 6.3版本中新增加了材质系统,极大地提高了室内场景的渲染效果和表现力。 材质系统的介绍 Lumion 6.3中新增加的材质系统,可以对模型的表面进行材质映射、标准化和纹理映射等操作,大大提高了模型表现的效果,让室内渲染效果更…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部