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

如何用AVFoundation获取1:1/16:9比例ProRAW图像及无损裁剪

获取1:1/16:9比例ProRAW图像及无损裁剪方案

一、通过AVFoundation直接获取对应比例的ProRAW

iPhone 11及以后机型的16:9/1:1 ProRAW确实是从传感器原生4:3画面裁剪而来,无需先获取4:3再手动裁剪,通过配置AVCapturePhotoOutput可直接得到对应比例输出:

  1. 配置ProRAW照片设置与目标比例
    先获取设备支持的ProRAW格式,再为照片设置指定目标比例:

    // 获取支持ProRAW的像素格式
    guard let rawFormat = capturePhotoOutput.availableRawPhotoPixelFormatTypes.first else {
        // 处理设备不支持ProRAW的情况
        return
    }
    
    // 创建ProRAW拍摄设置
    let photoSettings = AVCapturePhotoSettings(rawPixelFormatType: rawFormat)
    
    // 指定目标比例:1:1传CGSize(width:1, height:1),16:9传CGSize(width:16, height:9)
    let targetRatio = CGSize(width: 16, height: 9)
    if let matchedFormat = capturePhotoOutput.bestRawPhotoFormat(for: targetRatio, deliverablePreviewPixelFormatType: kCVPixelFormatType_32BGRA) {
        photoSettings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String: matchedFormat]
        photoSettings.maxPhotoDimensions = matchedFormat.dimensions
    }
    
    // 触发拍摄
    capturePhotoOutput.capturePhoto(with: photoSettings, delegate: self)
    
  2. 调整会话预设
    确保AVCaptureSession使用.photo预设,避免固定为4:3的分辨率限制:

    captureSession.sessionPreset = .photo
    

二、ProRAW无损裁剪方案

如果必须先获取4:3 ProRAW再裁剪,需基于DNG原始数据操作,避免转码损失:

用ImageIO实现无损裁剪(保留DNG格式)

import ImageIO

func cropProRAWToTargetRatio(rawURL: URL, targetRatio: CGSize) -> Data? {
    guard let imageSource = CGImageSourceCreateWithURL(rawURL as CFURL, nil) else { return nil }
    guard let rawProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [CFString: Any] else { return nil }
    
    // 获取原始图像尺寸
    let originalWidth = rawProperties[kCGImagePropertyPixelWidth] as! CGFloat
    let originalHeight = rawProperties[kCGImagePropertyPixelHeight] as! CGFloat
    let originalRatio = originalWidth / originalHeight
    
    // 计算居中裁剪区域
    var cropRect: CGRect
    if (targetRatio.width / targetRatio.height) > originalRatio {
        // 16:9比例,裁剪上下部分
        let targetHeight = originalWidth * targetRatio.height / targetRatio.width
        let yOffset = (originalHeight - targetHeight) / 2
        cropRect = CGRect(x: 0, y: yOffset, width: originalWidth, height: targetHeight)
    } else {
        // 1:1比例,裁剪左右部分
        let targetWidth = originalHeight * targetRatio.width / targetRatio.height
        let xOffset = (originalWidth - targetWidth) / 2
        cropRect = CGRect(x: xOffset, y: 0, width: targetWidth, height: originalHeight)
    }
    
    // 配置裁剪选项,保留RAW元数据
    let cropOptions: [CFString: Any] = [
        kCGImageSourceCreateThumbnailFromImageAlways: true,
        kCGImageSourceCreateThumbnailWithTransform: true,
        kCGImageSourceThumbnailMaxPixelSize: max(cropRect.width, cropRect.height),
        kCGImageSourceCropRect: cropRect
    ]
    
    guard let croppedCGImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, cropOptions as CFDictionary) else { return nil }
    
    // 将裁剪后的图像保存为DNG格式
    let outputData = NSMutableData()
    guard let imageDestination = CGImageDestinationCreateWithData(outputData, kUTTypeDNG, 1, nil) else { return nil }
    CGImageDestinationAddImage(imageDestination, croppedCGImage, rawProperties as CFDictionary)
    guard CGImageDestinationFinalize(imageDestination) else { return nil }
    
    return outputData as Data
}

三、现有代码调整建议

结合你提供的代码逻辑,需检查以下几点:

  • 确认是否为AVCapturePhotoSettings指定了匹配目标比例的maxPhotoDimensions或previewPhotoFormat;
  • 避免将captureSession.sessionPreset设置为固定比例的预设(如.hd1920x1080),保持为.photo;
  • 创建AVCapturePhotoSettings时,需明确关联ProRAW格式与目标比例的适配配置。

内容的提问来源于stack exchange,提问作者no13bus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:35:25