iOS 10将原始照片保存到相机胶卷

3
我有以下代码将RAW图像保存为JPEG格式到相机胶卷,但它有三个问题:1)它是镜像图像,2)它旋转了90度,3)它的分辨率很低。
// In my PhotoCaptureDelegate
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingRawPhotoSampleBuffer rawSampleBuffer: CMSampleBuffer?,     previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings:     AVCaptureBracketedStillImageSettings?, error: Error?) {

  if ( rawSampleBuffer != nil) {
    let temporaryDNGFileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(resolvedSettings.uniqueID)lld.dng")!
    let temporaryJPGFileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(resolvedSettings.uniqueID)lld.jpg")!
    let imageData = AVCapturePhotoOutput.dngPhotoDataRepresentation(forRawSampleBuffer: rawSampleBuffer!, previewPhotoSampleBuffer:       previewPhotoSampleBuffer)


    try! imageData?.write(to: temporaryDNGFileURL)
    PHPhotoLibrary.requestAuthorization({ (status)  in
        if status == .authorized {
          PHPhotoLibrary.shared().performChanges({

            let options = PHAssetResourceCreationOptions()
            options.shouldMoveFile = true
            //Write Raw:
            PHAssetCreationRequest.forAsset().addResource(with: .photo, fileURL: temporaryDNGFileURL, options: options)

                    // Process Raw to JPG
                    if let ciRawFilter = CIFilter(imageData: imageData! as Data, options: nil) {
                        let cs = CGColorSpace(name: CGColorSpace.displayP3)!
                        do {
                            try self.contextForSaving.writeJPEGRepresentation(of: ciRawFilter.outputImage!, to: temporaryJPGFileURL, colorSpace: cs,   options: [    kCGImageDestinationLossyCompressionQuality as String: 1.0])
                            PHAssetCreationRequest.forAsset().addResource(with: .photo, fileURL: temporaryJPGFileURL, options: options)
                        } catch _ {
                            print("error with jpeg conversion")
                        }

                    }
            }, completionHandler: { [unowned self] success, error in
              if let error = error {
                print("Error occurered while saving photo to photo library: \(error)")
              } else {
                print("Raw photo written to photo library.")
              }

              if FileManager.default.fileExists(atPath: temporaryDNGFileURL.path) {
                do {
                  (try FileManager.default.removeItem(at: temporaryDNGFileURL))
                }
                catch _ {
                  print("could not remove temporary file")
                }
              }
              self.didFinish()
            }
          )
        }
        else {
          self.didFinish()
        }
    })
  } else {
    print("Error capturing photo: \(error)")
  }
}

我知道如何直接捕获JPEG,但我正在尝试先对RAW数据应用一些自定义滤镜。

enter image description here

请帮忙如果你能的话,提前感谢!
2个回答

5
我已经测试了以下代码,可以保存来自原始滤镜的输出图像,以正确的方向和分辨率格式进行Jpeg格式。根据您的要求更改Jpeg质量和输出颜色空间。希望这可以帮助您。
    guard let opCiImage:CIImage = rawFilter!.outputImage else {
        print("Error in creating raw filter output")
        return
    }
    let dumpingContext:CIContext = CIContext(options: [kCIContextCacheIntermediates:false,
                                                       kCIContextPriorityRequestLow:false])



    //Convert to CGImage and then dump into a jpeg
    let opCgImage = dumpingContext.createCGImage(opCiImage,
                                                   from: opCiImage.extent,
                                                   format: kCIFormatARGB8,
                                                   colorSpace: CGColorSpace(name: CGColorSpace.sRGB),
                                                   deferred: false)
    let uImage = UIImage(cgImage: opCgImage!)
    guard let opImgData:Data = UIImageJPEGRepresentation(uImage, 0.95) else { return }

请在评论中告诉我反馈意见。

谢谢 @nav1729!你能回退几行并给我展示一下你是如何创建rawFilter的吗?我的尝试似乎没有起作用。我仍然得到一个颠倒的640x852。 let imageData = AVCapturePhotoOutput.dngPhotoDataRepresentation(forRawSampleBuffer: rawSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer) let ciRawFilter = CIFilter(imageData: imageData! as Data, options: nil) - Dan Hixon
@DanHixon,我也像你在自己的答案中提到的那样创建了原始过滤器。我使用了kCGImageSourceTypeIdentifierHint。我不知道那是关键。我只是模仿苹果的rawExpose示例应用程序。感谢您提供的信息。抱歉之前没有及时回复,因为我有一段时间没有查看邮件/网站。 - nav1729

2

我需要指定kCGImageSourceTypeIdentifierHint。它只是从DNG数据中获取JPEG缩略图表示,而不是查找实际的DNG数据。现在我已经设置了这个选项,JPEG文件是全尺寸且正确方向。

let imageData = AVCapturePhotoOutput.dngPhotoDataRepresentation(
                forRawSampleBuffer: rawSampleBuffer!, 
                previewPhotoSampleBuffer: previewPhotoSampleBuffer)
let rawOptions = [String(kCGImageSourceTypeIdentifierHint): "com.adobe.raw-image"]
if let ciRawFilter = CIFilter(imageData: imageData! as Data, options: rawOptions) {
  // raw Filters and stuff go here, then handle outputImage
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接