【问题标题】:Taking photo with custom camera iOS 11.0 Swift 4. Update error使用自定义相机拍照 iOS 11.0 Swift 4. 更新错误
【发布时间】:2018-03-10 17:39:04
【问题描述】:

我的应用中有一个自定义摄像头,它工作正常,但在新更新后我收到此错误:

'jpegPhotoDataRepresentation(forJPEGSampleBuffer:previewPhotoSampleBuffer:)' 在 iOS 11.0 中已弃用:请改用 -[AVCapturePhoto fileDataRepresentation]。

这是我收到该错误的行:

    guard let imageData =
        AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else {
            return
    }

这是我的全部功能(如果需要):

//Take pic function
func photoOutput(_ captureOutput: AVCapturePhotoOutput,
                 didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?,
                 previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
                 resolvedSettings: AVCaptureResolvedPhotoSettings,
                 bracketSettings: AVCaptureBracketedStillImageSettings?,
                 error: Error?) {


    // Make sure we get some photo sample buffer
    guard error == nil,
        let photoSampleBuffer = photoSampleBuffer else {
            print("Error capturing photo: \(String(describing: error))")
            return
    }
    // Convert photo same buffer to a jpeg image data by using // AVCapturePhotoOutput
    guard let imageData =
        AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else {
            return
    }

    let dataProvider = CGDataProvider(data: imageData as CFData)

    let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.absoluteColorimetric)


    let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.right)

    self.tempImageView.image = image

}

我的猜测是:我应该用什么来代替它?

谢谢。

【问题讨论】:

标签: swift xcode camera swift4 xcode9


【解决方案1】:

使用此代码 (Swift 5),它对我来说工作正常。

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    guard let imageData = photo.fileDataRepresentation() else { return }
    let previewImage = UIImage(data: imageData)
}

【讨论】:

  • 建议完全不同的方法而不是帮助修复主题启动者正在使用的方法有什么意义?
  • 怎么会有不同的方法呢?只需检查问题并再次阅读我的答案。如果您有解决方案,请在此处发布。 @PavelBogart
【解决方案2】:

对于 iOS 11.0 及更低版本我都处理过

var photoOutput : AVCapturePhotoOutput?

if #available(iOS 11.0, *)
{
                    photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])], completionHandler: nil)
} 

else
{
                    photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey:AVVideoCodecJPEG])], completionHandler: nil)
}

【讨论】:

    【解决方案3】:

    感谢@Vini App,我尝试了它对我有用的代码,我发布了我的图像捕获和处理代码,希望对在他们的应用程序中需要类似功能的人有所帮助。

    首先你需要设置你的视频捕捉设备,用谷歌搜索它是一个例子https://gist.github.com/tad-iizuka/fc35bc7835920c0b8b84e316f83e3a40

    确保您需要在顶部定义photoSetting

    ...
    var photoSetting = AVCapturePhotoSettings()
    ...
    

    viewDidLoad()viewWillAppear() 中配置照片设置

                // Configure camera
            photoSetting = AVCapturePhotoSettings.init(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])
            photoSetting.isAutoStillImageStabilizationEnabled = true
            photoSetting.flashMode = .off
    

    然后使用下面的函数来处理缓冲的图像数据

         func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    
        // Check if there is any error in capturing
        guard error == nil else {
            print("Fail to capture photo: \(String(describing: error))")
            return
        }
    
        // Check if the pixel buffer could be converted to image data
        guard let imageData = photo.fileDataRepresentation() else {
            print("Fail to convert pixel buffer")
            return
        }
    
        // Check if UIImage could be initialized with image data
        guard let capturedImage = UIImage.init(data: imageData , scale: 1.0) else {
            print("Fail to convert image data to UIImage")
            return
        }
    
        // Get original image width/height
        let imgWidth = capturedImage.size.width
        let imgHeight = capturedImage.size.height
        // Get origin of cropped image
        let imgOrigin = CGPoint(x: (imgWidth - imgHeight)/2, y: (imgHeight - imgHeight)/2)
        // Get size of cropped iamge
        let imgSize = CGSize(width: imgHeight, height: imgHeight)
    
        // Check if image could be cropped successfully
        guard let imageRef = capturedImage.cgImage?.cropping(to: CGRect(origin: imgOrigin, size: imgSize)) else {
            print("Fail to crop image")
            return
        }
    
        // Convert cropped image ref to UIImage
        imageToSave = UIImage(cgImage: imageRef, scale: 1.0, orientation: .down)
        UIImageWriteToSavedPhotosAlbum(imageToSave, nil, nil, nil)
    
        // Stop video capturing session (Freeze preview)
        captureSession.stopRunning()
    }
    

    在这个函数中,像素缓冲区被转换为photoSetting指定格式的图像数据,然后裁剪成你想要的大小。

    您可以在IB中创建一个按钮来调用上面的捕获函数

    @IBAction func onTakePhoto(_ sender: UIButton) {
        if let videoConnection = videoOutput.connection(with: AVMediaType.video) {
            // Adjust the orientaion of captured image
            let capturePhotoSetting = AVCapturePhotoSettings.init(from: photoSetting)
            videoConnection.videoOrientation = (previewLayer.connection?.videoOrientation)!
            // Save captured photo to system album
            self.videoOutput.capturePhoto(with: capturePhotoSetting, delegate: self)
        }
    }
    

    【讨论】:

    • 将 photoSetting up top 定义为变量对我不起作用,因为在拍摄第二张照片时,应用程序崩溃了,说我不允许使用照片设置。 AVCapturePhotoSettings 可以在每次拍照时在您的 IBAction 或其他函数中使用“let”(而不是 var)来定义,然后它可以在重复拍照时正常工作。
    • 嗨,@VagueExplanation,感谢您的回复,但我不太明白究竟是什么导致了崩溃(听起来像是每次实例化 AVCapturePhotoSetting?)。发布的代码在我的应用程序的“照相亭”视图中工作,所以基本上,您可以拍照并继续下一个您满意的视图,或者如果您不喜欢它,可以重新拍摄。照片保存到相册,应用程序在 iPad 上运行。希望这会有所帮助?或者您可以提供更多细节以供讨论?
    • 好吧,那没关系。这取决于你如何使用它。
    • 你能帮我解决这个问题吗?看起来很相似,但我需要这个stackoverflow.com/questions/49291753/…的旧版本@
    • 感谢代码!裁剪部分帮助了我:)
    【解决方案4】:

    在 iOS 11 中,你应该这样使用:

    @available(iOS 11.0, *)
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
            let imageData = photo.fileDataRepresentation()
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多