(九)深入了解AVFoundation-采集:拍照 摄像头切换、拍照参数和照片数据EXIF 信息

(一)深入了解AVFoundation:框架概述与核心模块解析-CSDN博客

(二) 深入了解AVFoundation - 播放:AVFoundation 播放基础入门-CSDN博客

(三)深入了解AVFoundation-播放:AVPlayer 进阶 播放状态 & 进度监听全解析_avplayer 播放状态-CSDN博客

(四)深入理解AVFoundation-播放:高度自定义视频播放器 UI-CSDN博客

(五)深入了解AVFoundation-播放:多音轨、字幕、倍速播放与横竖屏切换-CSDN博客

(六)深入了解AVFoundation-播放:AirPlay、画中画后台播放_air.av-CSDN博客

(七)深入了解AVFoundation-采集:采集系统架构与 AVCaptureSession 全面梳理_avcapturesession startrunning子线程调用-CSDN博客

(八)深入了解AVFoundation-采集:拍照功能的实现_ios avcapturephotooutput-CSDN博客

(九)深入了解AVFoundation-采集:拍照 摄像头切换、拍照参数和照片数据EXIF 信息-CSDN博客

(十)深入了解AVFoundation-采集:录制视频功能的实现-CSDN博客

(十一)深入了解AVFoundation-采集:二维码识别-CSDN博客

(十二)深入了解AVFoundation-采集:人脸识别与元数据处理-CSDN博客

引言

在 iOS 开发中,AVFoundation 提供了极为强大而灵活的拍照能力。在上一篇基础篇中,我们已经介绍了如何使用 AVCaptureSession 搭建一个基础的拍照流程。而在实际应用中,拍照功能远不止“按下快门”这么简单。

本篇将带你解锁 AVFoundation 拍照的进阶玩法,包括摄像头切换拍照参数的精细化配置(如分辨率、闪光灯、HDR)、实时滤镜的应用,以及如何获取照片的原始数据、EXIF 信息和 HEIF 格式支持。这些内容不仅能提升拍照质量,也让你的 App 拍照体验更专业、更智能。

无论你是想做一个具备滤镜选择的相机应用,还是实现媲美系统相机的照片输出控制,本篇都能为你提供全面的技术支持。

摄像头切换实现

在拍照功能中,前后摄像头的自由切换是用户最常见的需求之一。比如自拍和普通拍照之间的切换,其核心就是替换当前 AVCaptureDeviceInput,并对 AVCaptureSession 做一次重配置。

1. 获取可用摄像头设备

iOS的摄像头设备可以通过 AVCaptureDevice.DiscoverySession 获取,常见的类型包括前置摄像头和后置广角摄像头。

    /// 获取指定摄像头
    private func getCameraDevice(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
        let devices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: position).devices
        return devices.first
    }

2.实现切换逻辑

实现切换的核心逻辑是 开始配置->移除当前输入->添加新的输入->提交配置,整个过程建议放在session的beginConfiguration()和commitConfiguration()之间。

    /// 切换摄像头
    func switchCamera() {
        guard let currentInput = captureDeviceInput else { return }
        session.beginConfiguration()
        session.removeInput(currentInput)
        
        let newPosition: AVCaptureDevice.Position = (currentInput.device.position == .back) ? .front : .back
        guard let newDevice = getCameraDevice(position: newPosition) else {
            delegate?.captureError(NSError(domain: "PHCaptureController", code: 1005, userInfo: [NSLocalizedDescriptionKey: "Failed to get new camera device"]))
            return
        }
        setupSessionInput(device: newDevice)
        session.commitConfiguration()
    }

拍照参数配置

在拍照功能中,灵活配置拍照参数可以极大提升用户体验与照片质量。AVFoundation 提供了多个可调参数,开发者可以根据设备能力和用户需求选择合适的配置。

1.分辨率设置(Session预设)

分辨率并非直接设置在 AVCapturePhotoSettings 上,而是通过配置 AVCaptureSession 的 sessionPreset 实现。常见的 preset 有:

预设名

说明

.photo

高质量静态照片(默认推荐)

.high

高质量视频或图像

.medium

中等质量,适合上传或处理

.inputPriority

优先使用输入设备最高质量

2. 闪光灯控制(Flash Mode)

闪光灯设置依赖于设备支持情况和当前的 AVCapturePhotoSettings 实例:

    /// 拍照
    func takePhoto() {
        let settings = AVCapturePhotoSettings()
        settings.flashMode = .auto
        settings.isHighResolutionPhotoEnabled = true
        sessionQueue.async {
            self.photoOutput.capturePhoto(with: settings, delegate: self)
        }
    }

其中flashMode还可以是.on或者.off。

3. HDR(高动态范围)设置

iOS 支持的 HDR 功能主要有两类:传统自动 HDR 和虚拟设备融合(Dual/Triple Camera Fusion)。可通过如下方式启用:

let settings = AVCapturePhotoSettings()
settings.isHighResolutionPhotoEnabled = true

// 自动融合(适用于 iPhone 双摄以上设备)
settings.isAutoVirtualDeviceFusionEnabled = true

// 可选开启红眼自动去除
settings.isAutoRedEyeReductionEnabled = true

获取照片数据和 EXIF 信息

完成拍照触发后,我们会通过 AVCapturePhotoCaptureDelegate 获取到拍摄的照片数据。在这个过程中,我们不仅可以获得图像本身,还能读取包含曝光、设备信息、GPS 等的 EXIF 元数据,对调试和功能扩展都非常有用。

1. 捕获照片数据

在 AVCapturePhotoCaptureDelegate 的拍照完成回调方法里,我们可以直接获取到照片数据。

    //MARK: - AVCapturePhotoCaptureDelegate
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: (any Error)?) {
        if let error = error {
            delegate?.captureError(error)
            return
        }
        guard let imageData = photo.fileDataRepresentation() else {
            delegate?.captureError(NSError(domain: "PHCaptureController", code: 1003, userInfo: [NSLocalizedDescriptionKey: "Failed to get image data"]))
            return
        }
        guard let image = UIImage(data: imageData) else {
            delegate?.captureError(NSError(domain: "PHCaptureController", code: 1004, userInfo: [NSLocalizedDescriptionKey: "Failed to create image"]))
            return
        }
        delegate?.capturePhoto(image)
    }

这里的 photo.fileDataRepresentation() 返回的是 JPEG 或 HEIF 格式的压缩数据(取决于之前设置的编码格式)。

2. 获取原始元信息(Metadata)

除了图像数据,AVCapturePhoto 也提供了完整的 metadata 信息(包括 EXIF、TIFF、GPS、设备等):

let metadata = photo.metadata
print(metadata)

它是一个 [String: Any] 字典,常见字段如下:

Key

描述

{Exif}

曝光时间、ISO、焦距等

{TIFF}

相机厂商、型号、软件版本等

{GPS}

拍照时的位置(若有授权)

Orientation

图片方向

PixelWidth/Height

像素尺寸

我们可以这样来读取它的数据:

if let exif = metadata["{Exif}"] as? [String: Any] {
    let exposureTime = exif["ExposureTime"]
    let iso = exif["ISOSpeedRatings"]
    print("曝光时间:\(exposureTime ?? ""),ISO:\(iso ?? "")")
}

3.处理原始图像数据(CIImage)

如果你不使用 fileDataRepresentation(),而是想进一步对图像做处理(比如保存为 PNG、叠加图层等),也可以使用:

let pixelBuffer = photo.pixelBuffer
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)

或者

if let cgImageRepresentation = photo.cgImageRepresentation() {
    let cgImage = cgImageRepresentation.takeUnretainedValue()
    let uiImage = UIImage(cgImage: cgImage)
}

结语

本文围绕 AVFoundation 的拍照能力进行了进阶实践,包括:

  1. 摄像头切换实现:通过灵活切换前后摄像头,提升用户使用自由度;
  2. 拍照参数配置:涵盖分辨率、闪光灯、HDR 等设置,实现更丰富的拍照效果;
  3. 获取照片数据与 EXIF 信息:掌握图像数据的保存与元信息提取,构建后续图像处理和展示的基础。

这些功能构成了一套可扩展、可自定义的 iOS 拍照模块核心,对于有定制拍照需求的 App 开发者来说,是一个值得掌握的基础能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值