news 2026/5/11 22:00:18

告别Camera1!Android Camera2 API实战:从零搭建一个带拍照功能的简易相机App

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
告别Camera1!Android Camera2 API实战:从零搭建一个带拍照功能的简易相机App

Android Camera2 API实战:从零构建高性能相机应用

在移动应用开发领域,相机功能始终是用户体验的核心环节之一。随着Android 5.0(Lollipop)的发布,Google彻底重构了相机框架,推出了Camera2 API以替代已显老态的Camera1接口。这一变革不仅带来了更精细的硬件控制能力,也为开发者开辟了更广阔的创意空间。

1. Camera2 API架构解析

Camera2 API采用全新的管道(Pipeline)设计模式,将相机操作抽象为请求(Request)和会话(Session)的概念体系。这种设计显著提升了框架的灵活性和可控性,使开发者能够实现诸如手动曝光控制、高速连拍等Camera1难以企及的功能。

核心组件包括:

  • CameraManager:系统级服务,负责枚举和访问相机设备
  • CameraDevice:代表物理相机设备的抽象
  • CameraCaptureSession:管理相机数据流的传输管道
  • CaptureRequest:定义单次图像捕获的参数配置
  • CaptureResult:提供捕获操作的元数据反馈

与传统Camera1 API的简单回调机制不同,Camera2引入了状态机模型。典型工作流程如下:

// 伪代码展示Camera2基本工作流 CameraManager manager = (CameraManager) context.getSystemService(CAMERA_SERVICE); String cameraId = manager.getCameraIdList()[0]; manager.openCamera(cameraId, new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { // 设备就绪后创建会话 camera.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { // 会话就绪后构建并提交请求 CaptureRequest.Builder builder = camera.createCaptureRequest(TEMPLATE_PREVIEW); builder.addTarget(previewSurface); session.setRepeatingRequest(builder.build(), null, null); } }, null); } }, null);

2. 开发环境准备

2.1 基础配置要求

确保开发环境满足以下条件:

  • Android Studio 4.0+
  • Gradle插件版本7.0+
  • 编译SDK版本≥21(Android 5.0)
  • 目标设备系统版本≥5.0

build.gradle中添加必要依赖:

dependencies { implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'androidx.camera:camera-core:1.1.0' implementation 'androidx.camera:camera-camera2:1.1.0' }

2.2 权限声明

AndroidManifest.xml中添加相机和存储权限:

<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

注意:从Android 10开始,作用域存储限制要求使用MediaStore API替代直接文件访问

3. 相机功能实现详解

3.1 相机初始化流程

完整的相机初始化包含以下关键步骤:

  1. 获取CameraManager实例
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
  1. 检查相机特性
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = characteristics.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); Size[] previewSizes = map.getOutputSizes(SurfaceTexture.class);
  1. 打开相机设备
manager.openCamera(cameraId, new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { // 设备准备就绪 } @Override public void onDisconnected(@NonNull CameraDevice camera) { camera.close(); } }, null);

3.2 预览功能实现

预览功能需要配置SurfaceView或TextureView作为渲染目标:

// 创建预览Surface SurfaceTexture texture = textureView.getSurfaceTexture(); texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); Surface previewSurface = new Surface(texture); // 创建会话 cameraDevice.createCaptureSession(Arrays.asList(previewSurface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { // 构建预览请求 CaptureRequest.Builder builder = cameraDevice.createCaptureRequest( CameraDevice.TEMPLATE_PREVIEW); builder.addTarget(previewSurface); session.setRepeatingRequest(builder.build(), null, null); } }, null);

3.3 拍照功能实现

拍照流程需要配置ImageReader接收图像数据:

// 初始化ImageReader ImageReader imageReader = ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); imageReader.setOnImageAvailableListener(reader -> { Image image = reader.acquireNextImage(); // 处理图像数据 image.close(); }, handler); // 构建拍照请求 CaptureRequest.Builder builder = cameraDevice.createCaptureRequest( CameraDevice.TEMPLATE_STILL_CAPTURE); builder.addTarget(imageReader.getSurface()); session.capture(builder.build(), null, null);

4. 高级功能开发技巧

4.1 手动控制参数

Camera2允许精细控制各种相机参数:

// 手动设置曝光时间(纳秒) builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 10000000L); // 设置ISO感光度 builder.set(CaptureRequest.SENSOR_SENSITIVITY, 800); // 手动对焦 builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.5f);

4.2 连拍功能实现

通过批量提交请求实现高速连拍:

List<CaptureRequest> requests = new ArrayList<>(); for (int i = 0; i < 10; i++) { CaptureRequest.Builder builder = cameraDevice.createCaptureRequest( CameraDevice.TEMPLATE_STILL_CAPTURE); builder.addTarget(imageReader.getSurface()); requests.add(builder.build()); } session.captureBurst(requests, null, null);

4.3 图像后处理管道

结合RenderScript实现实时滤镜效果:

// 创建输入/输出Allocation Allocation input = Allocation.createFromBitmap(rs, inputBitmap); Allocation output = Allocation.createTyped(rs, input.getType()); // 创建并执行脚本 ScriptC_grayscale grayscale = new ScriptC_grayscale(rs); grayscale.forEach_root(input, output); output.copyTo(outputBitmap);

5. 性能优化实践

5.1 内存管理策略

优化项实现方法效果评估
Surface复用使用SurfaceView替代TextureView减少30%内存拷贝
图像缓冲区合理设置ImageReader的maxImages平衡延迟与内存占用
请求批处理使用captureBurst替代多次capture提升15%连拍速度

5.2 异步操作模式

关键操作应使用Handler切换到非UI线程:

HandlerThread thread = new HandlerThread("CameraBackground"); thread.start(); Handler handler = new Handler(thread.getLooper()); manager.openCamera(cameraId, new CameraDevice.StateCallback() { // ... }, handler);

5.3 错误处理机制

完善的错误处理应包含以下场景:

  • 相机权限被拒绝
  • 设备被其他应用占用
  • 不支持的参数组合
  • 低光照条件下的对焦失败
@Override public void onError(@NonNull CameraDevice camera, int error) { switch (error) { case ERROR_CAMERA_DEVICE: // 致命错误,需要重新初始化 break; case ERROR_CAMERA_DISABLED: // 设备策略限制 break; case ERROR_CAMERA_IN_USE: // 相机被占用 break; } camera.close(); }

在Camera2 API的实际应用中,调试复杂的异步回调链往往最具挑战性。建议使用系统提供的Camera2Basic示例作为起点,逐步添加功能模块。当遇到图像方向问题时,检查CameraCharacteristics.SENSOR_ORIENTATION;当预览卡顿时,确认是否错误地使用了阻塞式图像处理方式。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 21:55:33

3分钟永久保存微博记忆:Speechless让数字回忆永不褪色

3分钟永久保存微博记忆&#xff1a;Speechless让数字回忆永不褪色 【免费下载链接】Speechless 把新浪微博的内容&#xff0c;导出成 PDF 文件进行备份的 Chrome Extension。 项目地址: https://gitcode.com/gh_mirrors/sp/Speechless 你是否曾经有过这样的经历&#xf…

作者头像 李华
网站建设 2026/5/11 21:53:31

深度解析:如何构建广谱注入Chromium/V8的通用修改器

深度解析&#xff1a;如何构建广谱注入Chromium/V8的通用修改器 【免费下载链接】chromatic Universal modifier for Chromium/V8 | 广谱注入 Chromium/V8 的通用修改器 项目地址: https://gitcode.com/gh_mirrors/be/chromatic Chromatic 是一款专为 Chromium/V8 引擎设…

作者头像 李华
网站建设 2026/5/11 21:53:00

如何快速配置chromatic:Chromium/V8广谱注入的5大核心功能解析

如何快速配置chromatic&#xff1a;Chromium/V8广谱注入的5大核心功能解析 【免费下载链接】chromatic Universal modifier for Chromium/V8 | 广谱注入 Chromium/V8 的通用修改器 项目地址: https://gitcode.com/gh_mirrors/be/chromatic chromatic是一个面向Chromium/…

作者头像 李华
网站建设 2026/5/11 21:47:15

H3C WA5320云AP瘦转胖实战:从BootWare升级到固件刷写的完整避坑指南

H3C WA5320云AP瘦转胖模式转换全流程精解&#xff1a;从底层原理到实战避坑 当企业网络架构需要灵活调整时&#xff0c;将云管理模式下的瘦AP转换为独立运行的胖AP成为许多网络工程师的刚需技能。以H3C WA5320这款经典商用无线接入点为例&#xff0c;其模式转换过程涉及BootWar…

作者头像 李华