22 votes

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

J'ai une caméra personnalisée dans mon application et cela fonctionnait bien, mais après la nouvelle mise à jour, je reçois cette erreur :

L'expression "jpegPhotoDataRepresentation(forJPEGSampleBuffer:previewPhotoSampleBuffer :)" est obsolète dans iOS 11.0 : utilisez -[AVCapturePhoto fileDataRepresentation] à la place.

C'est la ligne où j'obtiens cette erreur :

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

Voici l'ensemble de 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 question est la suivante : Que dois-je utiliser à la place pour que cela fonctionne ?

Merci.

37voto

Vini App Points 4968

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

10voto

infinity_coding7 Points 113

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

Tout d'abord, vous devez configurer votre dispositif de capture vidéo, recherchez-le sur Google ; voici un exemple. https://gist.github.com/tad-iizuka/fc35bc7835920c0b8b84e316f83e3a40

Assurez-vous que vous devez définir photoSetting au sommet

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

Configurez le paramètre photo soit dans viewDidLoad() o 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 mises 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 dans le format spécifié par photoSetting et ensuite recadrée à la taille que vous voulez.

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

0voto

karan Points 31

Pour iOS 11.0 et les versions inférieures, j'ai manipulé

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X