web-dev-qa-db-fra.com

Prendre une photo avec un appareil photo personnalisé iOS 11.0 Swift 4. Erreur de mise à jour

J'ai un appareil photo personnalisé dans mon application et cela a bien fonctionné, mais après la nouvelle mise à jour, je reçois cette erreur:

'jpegPhotoDataRepresentation (forJPEGSampleBuffer: previewPhotoSampleBuffer :)' a été déconseillé dans iOS 11.0: utilisez plutôt [AVCapturePhoto fileDataRepresentation].

C'est la ligne où je reçois cette erreur:

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

C'est toute ma fonction (si nécessaire):

//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

}

Ma suggestion est: Que dois-je utiliser à la place pour le faire fonctionner?

Merci.

22
0ndre_

Dans iOS 11, vous devez utiliser comme ceci:

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

Merci @Vini App, j'ai essayé le code qui a fonctionné pour moi, j'ai publié mon code pour la capture et le traitement d'images, j'espère que cela aidera les personnes qui ont besoin d'une fonction similaire dans leur application.

Vous devez d'abord configurer votre appareil de capture vidéo, recherchez-le sur Google ici, c'est un exemple https://Gist.github.com/tad-iizuka/fc35bc7835920c0b8b84e316f83e3a4

S'assure que vous devez définir photoSetting en haut

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

Configurez le paramètre photo soit dans viewDidLoad() ou viewWillAppear()

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

Utilisez ensuite la fonction suivante pour traiter les données d'image en mémoire tampon

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

Dans cette fonction, le tampon de pixels est converti en données d'image au format spécifié par photoSetting puis rogné à la taille souhaitée.

Vous pouvez créer un bouton dans IB pour appeler la fonction de capture ci-dessus

@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)
    }
}
10
infinity_coding7

Pour iOS 11.0 et inférieur, j'ai géré

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)
}
0
karan