You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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))")
    }
}

注意事项:

  1. 需在Info.plist中添加NSCameraUsageDescription权限描述
  2. 该代码仅可在实体iOS设备上运行,模拟器不支持相机RAW输出
  3. iOS 14.0及以上系统才可使用该RAW拍摄接口

内容的提问来源于stack exchange,提问作者Francesco Piraneo G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:15:07