能否在UIImagePickerController相机中启用人像模式(景深效果)?
能否通过UIImagePickerController启用人像模式自拍?
答案是不能。UIImagePickerController是苹果提供的轻量级相机封装组件,仅开放了基础的相机配置选项(如切换前后置、选择拍照/录像模式),并没有提供控制人像模式这类高级拍摄功能的接口,所以无法通过它直接启用人像模式。
替代方案:使用AVFoundation框架实现人像模式自拍
要实现类似系统相机的人像模式自拍,需要直接使用AVFoundation框架与相机硬件交互,配置深度数据捕获功能(人像模式的核心是深度信息采集)。以下是实现思路和简化代码示例:
核心步骤
- 检查设备前置摄像头是否支持深度数据传输
- 配置AVCaptureSession,添加摄像头输入和照片输出
- 启用深度数据捕获功能
- 实现照片拍摄逻辑,获取带深度信息的照片
代码示例
import AVFoundation import UIKit class PortraitCameraVC: UIViewController { private let captureSession = AVCaptureSession() private var previewLayer: AVCaptureVideoPreviewLayer! private let photoOutput = AVCapturePhotoOutput() override func viewDidLoad() { super.viewDidLoad() setupPortraitCamera() // 添加自定义拍摄按钮 let captureBtn = UIButton(type: .system) captureBtn.setTitle("拍摄人像", for: .normal) captureBtn.addTarget(self, action: #selector(takePortraitPhoto), for: .touchUpInside) captureBtn.frame = CGRect(x: view.center.x - 80, y: view.frame.height - 120, width: 160, height: 44) view.addSubview(captureBtn) } private func setupPortraitCamera() { // 配置会话预设为照片模式,支持高分辨率 captureSession.sessionPreset = .photo // 获取支持视频捕获的前置广角摄像头 guard let frontCamera = AVCaptureDevice.default( .builtInWideAngleCamera, for: .video, position: .front ) else { print("前置摄像头不可用") return } // 检查并启用深度数据传输(人像模式依赖) guard frontCamera.isDepthDataDeliveryEnabled else { print("当前设备不支持前置摄像头人像模式") return } do { try frontCamera.lockForConfiguration() frontCamera.isDepthDataDeliveryEnabled = true frontCamera.unlockForConfiguration() } catch { print("配置深度数据失败:\(error.localizedDescription)") return } // 添加摄像头输入到会话 do { let cameraInput = try AVCaptureDeviceInput(device: frontCamera) if captureSession.canAddInput(cameraInput) { captureSession.addInput(cameraInput) } } catch { print("添加摄像头输入失败:\(error.localizedDescription)") return } // 添加照片输出并启用深度数据捕获 if captureSession.canAddOutput(photoOutput) { captureSession.addOutput(photoOutput) photoOutput.isDepthDataDeliveryEnabled = photoOutput.isDepthDataDeliverySupported } // 创建预览层并显示相机画面 previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.frame = view.bounds previewLayer.videoGravity = .resizeAspectFill view.layer.insertSublayer(previewLayer, at: 0) // 启动相机会话 captureSession.startRunning() } @objc private func takePortraitPhoto() { let photoSettings = AVCapturePhotoSettings() // 确保启用深度数据捕获 if photoOutput.isDepthDataDeliveryEnabled { photoSettings.isDepthDataDeliveryEnabled = true } photoOutput.capturePhoto(with: photoSettings, delegate: self) } } extension PortraitCameraVC: AVCapturePhotoCaptureDelegate { func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { if let error = error { print("拍摄失败:\(error.localizedDescription)") return } // 获取包含深度信息的照片数据 guard let imageData = photo.fileDataRepresentation(), let portraitImage = UIImage(data: imageData) else { print("无法处理照片数据") return } // 后续可将照片显示到UIImageView或保存到相册 print("成功拍摄人像模式照片") } }
注意事项
- 必须在
Info.plist中添加相机权限申请:NSCameraUsageDescription,填写相机使用的原因(如"需要使用相机拍摄人像照片"),否则应用会崩溃 - 部分旧款iOS设备不支持前置摄像头的人像模式,需要提前做兼容性检查
- 如果设备不支持硬件级人像模式,也可以通过Core Image框架为普通照片添加手动模糊效果,但效果不如原生硬件模式自然
内容的提问来源于stack exchange,提问作者Jarutais
相关产品推荐
相关产品推荐

