iPhone拍摄RAW图像时availableRawPhotoPixelFormatTypes为空问题求助
问题排查思路
- 检查
AVCapturePhotoOutput是否已被正确添加到已启动的AVCaptureSession中:availableRawPhotoPixelFormatTypes属性只有在输出被关联到运行中的会话后才会返回有效值,未加入会话的输出实例该属性恒为空 - 检查
AVCaptureSession的预设配置:需要使用支持RAW输出的预设,比如AVCaptureSessionPresetPhoto,部分低分辨率预设不支持RAW拍摄 - 检查相机设备是否正确配置:需要先确认选中的广角摄像头本身支持RAW输出,iPhone 11 Pro的广角是支持的,但要注意切换摄像头后需要重新查询可用格式
- 检查权限配置:项目Info.plist必须已添加
NSCameraUsageDescription权限声明,未获取相机权限时会话无法正常启动,也会导致RAW格式查询为空
完整RAW拍摄示例代码
import UIKit import AVFoundation class RAWCameraViewController: UIViewController { private let captureSession = AVCaptureSession() private let photoOutput = AVCapturePhotoOutput() private var previewLayer: AVCaptureVideoPreviewLayer? override func viewDidLoad() { super.viewDidLoad() setupCamera() addCaptureButton() } private func setupCamera() { // 请求相机权限 AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in guard granted else { return } DispatchQueue.global(qos: .userInitiated).async { self?.configureCaptureSession() } } } private func configureCaptureSession() { // 配置会话预设为照片模式 captureSession.sessionPreset = .photo // 获取广角摄像头 guard let device = AVCaptureDevice.DiscoverySession( deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back ).devices.first else { return } // 配置设备输入 do { let input = try AVCaptureDeviceInput(device: device) if captureSession.canAddInput(input) { captureSession.addInput(input) } // 添加照片输出到会话 if captureSession.canAddOutput(photoOutput) { captureSession.addOutput(photoOutput) // 此时查询RAW格式才会有值 let rawFormats = photoOutput.availableRawPhotoPixelFormatTypes print("可用RAW格式: \(rawFormats)") } // 启动会话 captureSession.startRunning() // 配置预览层 DispatchQueue.main.async { let previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession) previewLayer.frame = self.view.bounds previewLayer.videoGravity = .resizeAspectFill self.view.layer.insertSublayer(previewLayer, at: 0) self.previewLayer = previewLayer } } catch { print("相机配置失败: \(error)") } } private func addCaptureButton() { let captureButton = UIButton(frame: CGRect(x: (view.bounds.width - 80)/2, y: view.bounds.height - 120, width: 80, height: 80)) captureButton.backgroundColor = .white captureButton.layer.cornerRadius = 40 captureButton.addTarget(self, action: #selector(captureRAWPhoto), for: .touchUpInside) view.addSubview(captureButton) } @objc private func captureRAWPhoto() { guard let rawFormat = photoOutput.availableRawPhotoPixelFormatTypes.first else { print("无可用RAW格式") return } // 配置RAW拍摄设置 let photoSettings = AVCapturePhotoSettings(rawPixelFormatType: rawFormat) // 可选:同时输出JPEG预览 if let previewFormat = photoSettings.availablePreviewPhotoPixelFormatTypes.first { photoSettings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewFormat] } photoOutput.capturePhoto(with: photoSettings, delegate: self) } } extension RAWCameraViewController: AVCapturePhotoCaptureDelegate { func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingRawPhoto rawSampleBuffer: CMSampleBuffer?, previewSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { guard let rawBuffer = rawSampleBuffer, error == nil else { print("RAW拍摄失败: \(error?.localizedDescription ?? "未知错误")") return } // 此处处理RAW数据,可转换为DNG文件存储 print("RAW拍摄成功,数据大小: \(CMSampleBufferGetTotalSampleSize(rawBuffer))") } }
注意事项:
- 需在Info.plist中添加
NSCameraUsageDescription权限描述- 该代码仅可在实体iOS设备上运行,模拟器不支持相机RAW输出
- iOS 14.0及以上系统才可使用该RAW拍摄接口
内容的提问来源于stack exchange,提问作者Francesco Piraneo G.
相关产品推荐
相关产品推荐

