移动开发中的相机:定义、API类型及使用方法

作者: IT Sectr 发布日期: 2026-03-22 阅读时间: 8 分钟

移动应用中的相机 — 是一种设备硬件模块,开发人员可通过系统API访问以捕获图像和视频。根据 Google Android Developers (2025),CameraX被用于超过85%需要相机功能的Android应用中。iOS上的AVFoundation和Android上的CameraX提供了隐藏硬件管理复杂性的高级接口。

要点

  • 相机在移动应用中通过系统API进行管理:Android上使用CameraX和Camera2,iOS上使用AVFoundation。
  • CameraX — 现代化的Jetpack库,具有生命周期管理,支持95%的Android设备。
  • AVFoundation — iOS框架,用于捕获视频和照片,支持Exposure、ISO和Focus设置。
  • 权限在两个平台上都必须获取相机访问权限,通过系统对话框请求。
  • 性能相机性能取决于设备的硬件能力和操作系统版本。

什么是移动应用中的相机

移动相机 — 是一个内置光学模块,由镜头、矩阵(传感器)和图像处理处理器(ISP)组成。开发人员通过操作系统使用特定框架访问相机。在Android上是Camera2 API(低级)和CameraX(基于Camera2的高级),在iOS上是AVFoundation和用于简单场景的UIKit。每个平台提供自己的工具集,但总体概念相同:应用初始化捕获会话,配置参数(分辨率、对焦、曝光)并接收帧流或单个图像。

现代相机的硬件能力

现代移动相机支持多种拍摄模式:HDR、夜景模式、背景虚化的人像、慢动作和RAW格式录制。开发人员可以使用软件设置:ISO(矩阵灵敏度)、曝光时间、白平衡、对焦(自动和手动)和图像稳定。在旗舰设备上多达4个具有不同焦距的相机可用,应用可以根据ID选择特定相机。

相机API的类型

在移动平台上存在几种用于相机工作的API,它们在抽象级别和功能上有所不同。具体API的选择取决于项目需求:对于简单的照片拍摄,CameraX或UIImagePickerController就足够了,对于专业应用需要Camera2或具有直接传感器控制的AVFoundation。以下是主要API的比较。

API平台级别特点
CameraXAndroid高级生命周期感知,95%设备
Camera2Android低级完全控制,RAW,连拍
AVFoundationiOS中级完全捕获控制
UIKit(UIImagePickerController)iOS高级现成UI,无法自定义

何时选择CameraX

CameraX — 对于大多数不需要深度自定义的Android应用来说是最佳选择。该库自动管理Activity和Fragment的生命周期,支持权限和不同Android版本的兼容性。CameraX通过兼容层保证在95%的Android设备上具有相同的行为。如果需要相机预览(Preview)、照片捕获(ImageCapture)或流分析(ImageAnalysis) — CameraX无需编写复杂代码即可处理所有三个场景。

何时选择Camera2

Camera2 — 用于专业场景的低级API:RAW录制、手动曝光设置、连拍(burst)、同时控制多个相机。Camera2要求开发人员深入了解图像捕获管道、StateMachine管理和回调处理。仅当CameraX不满足需求时才使用Camera2:例如,用于需要手动对焦的文档扫描应用或具有非标准分辨率的自定义相机。

请求相机访问权限

访问相机需要在两个平台上获得用户的明确同意。在Android上,在清单中添加CAMERA权限,从Android 6.0开始还需要通过ActivityCompat.requestPermissions在运行时请求权限。在iOS上,在Info.plist中添加NSCameraUsageDescription键,附带相机使用原因的说明。没有此说明,应用在尝试访问相机时会崩溃。从iOS 14开始,权限对话框不仅显示应用名称,还显示所述原因 — 措辞应对用户可理解。

在Android上使用CameraX实现

CameraX将相机工作简化为几行代码。要启动预览,需要创建Preview实例,将其绑定到LifecycleOwner并获取SurfaceProvider进行显示。对于照片捕获,使用带有保存目标的ImageCapture。以下是在Kotlin中使用CameraX启动相机和拍摄照片的完整示例。

配置Preview和ImageCapture

kotlin
val preview = Preview.Builder()
    .build()
    .also {
        it.surfaceProvider = viewFinder.surfaceProvider
    }

val imageCapture = ImageCapture.Builder()
    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
    .build()

val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
    val cameraProvider = cameraProviderFuture.get()
    val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

    try {
        cameraProvider.unbindAll()
        cameraProvider.bindToLifecycle(
            this, cameraSelector, preview, imageCapture
        )
    } catch (e: Exception) {
        Log.e("CameraX", "绑定失败", e)
    }
}, ContextCompact.getMainExecutor(this))

bindToLifecycle方法将相机与Activity的生命周期绑定 — 在屏幕旋转或进入后台时,相机会自动释放。CameraSelector.DEFAULT_BACK_CAMERA选择后置相机,前置相机使用DEFAULT_FRONT_CAMERA。绑定后,Preview开始在PreviewView中显示相机图像,用户在屏幕上看到相机画面。

拍摄照片

kotlin
val photoFile = File(
    externalMediaDirs.firstOrNull(),
    "IMG_${System.currentTimeMillis()}.jpg"
)
val outputOptions = ImageCapture.OutputFileOptions
    .Builder(photoFile)
    .build()

imageCapture.takePicture(
    outputOptions,
    ContextCompact.getMainExecutor(this),
    object : ImageCapture.OnImageSavedCallback {
        override fun onImageSaved(output: ImageCapture.OutputFileResults) {
            Log.d("CameraX", "Photo saved: ${photoFile.absolutePath}")
        }
        override fun onError(exception: ImageCaptureException) {
            Log.e("CameraX", "捕获错误", exception)
        }
    }
)

takePicture方法从相机捕获帧并将其保存到文件。OutputFileOptions支持保存到File、ContentResolver和MediaStore。在onImageSaved回调中,应用收到成功保存的通知并可以更新UI。CAPTURE_MODE_MINIMIZE_LATENCY通过减少后处理确保最大快门速度。

在iOS上使用AVFoundation实现

在iOS上,访问相机由AVFoundation框架通过AVCaptureSession类提供。开发人员创建捕获会话,添加必要的输入(AVCaptureDeviceInput)和输出(AVCapturePhotoOutput、AVCaptureVideoDataOutput)并启动会话。预览显示使用AVCaptureVideoPreviewLayer。以下是在Swift中配置会话以捕获照片的示例。

swift
import AVFoundation

let captureSession = AVCaptureSession()
captureSession.sessionPreset = .photo

guard let camera = AVCaptureDevice.default(
    for: .video
) else { return }

guard let input = try? AVCaptureDeviceInput(device: camera)
else { return }

let output = AVCapturePhotoOutput()
captureSession.addInput(input)
captureSession.addOutput(output)

DispatchQueue.global(qos: .userInitiated).async {
    captureSession.startRunning()
}

AVCaptureSessionPreset.photo设置照片的最佳分辨率(通常在现代设备上为12 MP)。输入是为设备相机创建的AVCaptureDeviceInput。添加输入和输出后,会话通过startRunning在后台线程中启动 — 在旧设备上会话启动可能需要长达200毫秒。要捕获照片,调用capturePhoto(with:delegate:),结果通过委托AVCapturePhotoCaptureDelegate返回。

特点与限制

在移动设备上使用相机时需考虑硬件限制:长时间拍摄时设备发热、高分辨率工作时电池消耗以及不同设备上相机质量各异。在Android上,生态系统碎片化导致相同的CameraX配置在不同型号上可能表现不同。在iOS上,限制主要涉及许可:在后台使用相机需要Apple的特别许可。同样重要的是要记住,模拟器无法访问真实相机 — 测试只能在物理设备上进行。

与不同操作系统版本的兼容性

CameraX通过CameraXConfig兼容层解决Android碎片化问题 — 库自动应用针对制造商已知错误的解决方案。在iOS上,AVFoundation从iOS 6开始在所有设备上统一运行,但某些功能(如Portrait Mode或LiDAR)仅适用于iPhone 12及更新型号。在开发跨平台应用时,建议使用Flutter或React Native配合相机插件 — 它们抽象了平台差异并为两个操作系统提供统一的API。

常见问题

在Android上应该选择哪个相机API?

对于大多数应用,推荐使用CameraX,因为其使用简单、内置生命周期处理以及与95%设备的兼容性。Camera2仅在需要RAW、连拍或手动传感器控制时选择。

如何请求相机访问权限?

Android上,在清单中添加CAMERA权限并在运行时通过ActivityCompat.requestPermissions请求。在iOS上,在Info.plist中添加NSCameraUsageDescription,附带相机使用原因的清晰说明。

可以在后台使用相机吗?

在iOS上,后台使用相机受到严格限制 — 需要Apple的特别许可。在Android上,相机可以通过前台服务(foreground service)在后台工作,但这会对电池电量和设备发热产生负面影响。

为什么相机在模拟器上无法工作?

iOS模拟器和Android模拟器无法访问硬件相机 — 它们不模拟物理传感器。要测试相机功能,始终使用物理设备或连接到计算机的外部相机。

什么是CameraX ImageAnalysis?

ImageAnalysis — 来自CameraX的帧流分析器,它将每个帧传递给ImageAnalysis.Analyzer进行处理。用于QR码识别、人脸检测、文档扫描和其他计算机视觉任务。

总结

  • 相机在移动应用中通过CameraX/Camera2(Android)和AVFoundation(iOS)进行管理。
  • CameraX — 高级Jetpack库,支持生命周期并与95%的Android设备兼容。
  • AVFoundation提供AVCaptureSession,用于在iOS上灵活管理图像和视频捕获。
  • 权限在两个平台上都是必需的 — Android上的CAMERA,iOS上的NSCameraUsageDescription。
  • Camera2 — 用于专业场景的低级API:RAW、手动设置、连拍。
  • 限制 — 设备发热、Android碎片化、模拟器中缺乏相机仿真。
  • 建议 — 从Android上的CameraX和iOS上的AVFoundation开始,仅在必要时切换到Camera2。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读