【问题标题】:How to save JPEG/RAW image data to camera roll in iOS 11, can't access processed image data如何在 iOS 11 中将 JPEG/RAW 图像数据保存到相机胶卷,无法访问处理后的图像数据
【发布时间】:2018-10-09 06:52:41
【问题描述】:

我正在尝试编写一个可以同时拍摄 RAW 和 JPEG 图像并将它们保存到相机胶卷的照片应用程序。函数 jpegPhotoDataRepresentation 和 dngPhotoDataRepresentation 似乎是我找到的所有示例的关键,但是这两个在 iOS 11 中都已弃用,并且在“capturePhoto”之后保存的功能现在是

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

我能够找到一个工作的 RAW iOS11 应用程序的主要示例是这样的: https://ubunifu.co/swift/raw-photo-capture-sample-swift-4-ios-11 这可行,但是它只拍摄 RAW 并且保存很笨拙,因为它不在相机胶卷上。

我已经更改了我的照片设置,以允许使用这条线进行原始和处理后的拍摄

photoSettings = AVCapturePhotoSettings(rawPixelFormatType: availableRawFormat.uint32Value, processedFormat: [AVVideoCodecKey : AVVideoCodecType.jpeg])

但是,一旦我实际拍摄了照片,我就不知道如何访问已处理的格式数据。 fileDataRepresentation 似乎是访问 dng 内容的唯一方法,但是没有办法单独获取 jpeg 吗?我从 Apple pre-iOS11 中找到的代码建议使用 PHPhotoLibrary 并添加一个资源,但这需要一个数据表示,除了作为 dng 文件之外我无法访问,当保存到库时只是白色的,因为该库无法处理 RAW 文件。这是我的 photoOutput 代码,以防万一。

 func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

    let dir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyyMMddHHmmss"
    formatter.locale = Locale.init(identifier: "en_US_POSIX")
    let filePath =  dir.appending(String(format: "/%@.dng", formatter.string(from: Date())))
    let dngFileURL = URL(fileURLWithPath: filePath)

    let dngData = photo.fileDataRepresentation()!
    do {
        try dngData.write(to: dngFileURL, options: [])
    } catch {
        print("Unable to write DNG file.")
        return
    }

    PHPhotoLibrary.shared().performChanges( {
        let creationRequest = PHAssetCreationRequest.forAsset()
        let creationOptions = PHAssetResourceCreationOptions()
        creationOptions.shouldMoveFile = true


        //dngData is the problem, this should be the jpeg representation
        creationRequest.addResource(with: .photo, data: dngData, options: nil)
        //This line works fine, the associated file is the correct RAW file, but the jpeg preview is garbage
        creationRequest.addResource(with: .alternatePhoto, fileURL: dngFileURL, options: creationOptions)

    }, completionHandler: nil)

}

【问题讨论】:

标签: ios swift camera jpeg ios11


【解决方案1】:

好的,跟进之前的评论和Capturing Photos in RAW Format 上的 Apple 文档:

如您所见,如果您想拍摄 RAW 并将其保存在照片库中,您需要将 DNG+处理后的版本一起保存在同一资源中,以便不支持 RAW 的照片库客户端仍然拥有资产的可读版本。 (这包括照片应用程序本身......)同时保存 RAW+已处理意味着在捕获中指定它。

如果您请求 RAW+ 处理过的捕捉(其中处理过的是 JPEG,或者更好的是 HEIF),那么您每次拍摄都会获得两张照片。这意味着您的didFinishProcessingPhoto 回调被调用两次:一次传送JPEG(或HEIF),再次传送RAW。

由于您需要将资产的 RAW + 处理版本一起添加到照片中,因此您应该等到捕获输出提供两个版本后再尝试创建照片资产。您会注意到 Apple doc 中的代码 sn-ps 将两个版本的数据存储在 didFinishProcessingPhoto 回调中:

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if photo.isRawPhoto {
        // Save the RAW (DNG) fileDataRepresentation to a URL
    } else {
        // Hold JPEG/HEIF fileDataRepresentation in a property
    }
}

然后,当didFinishCaptureFor 回调触发时,他们确保它们具有两个版本,并将它们一起添加到照片库中。

请注意,当您将 DNG 和 JPEG 或 HEIF 版本的照片一起添加时...

  • JPEG/HEIF 需要是主要的 photo 资源,而 DNG 需要是 alternatePhoto 资源。
  • 您可以直接从内存中的Data 添加 JPEG/HEIF 资源,但需要从文件 URL 添加 DNG。

所以照片库部分是这样的(同样,在didFinishCaptureFor 回调中):

PHPhotoLibrary.shared().performChanges({
    // Add the compressed (HEIF) data as the main resource for the Photos asset.
    let creationRequest = PHAssetCreationRequest.forAsset()
    creationRequest.addResource(with: .photo, data: compressedData, options: nil)

    // Add the RAW (DNG) file as an altenate resource.
    let options = PHAssetResourceCreationOptions()
    options.shouldMoveFile = true
    creationRequest.addResource(with: .alternatePhoto, fileURL: rawURL, options: options)
}, completionHandler: self.handlePhotoLibraryError)

【讨论】:

  • 这对我有用,你的解释很有意义。存储来自不同回调的两张照片是诀窍。谢谢。
猜你喜欢
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 2015-02-16
相关资源
最近更新 更多