2016-06-16 8 views
27

ich dies zusammen mit Swift 3. Ich hatte ursprünglich zu Xcode 8 Beta eine eigene Kamera mit, und ich vor kurzem ein Upgrade gearbeitet haben:Wie AVCapturePhotoOutput verwenden

var stillImageOutput: AVCaptureStillImageOutput? 

Aber ich bin jetzt immer die Warnung :

'AVCaptureStillImageOutput' was deprecated in iOS 10.0: Use AVCapturePhotoOutput instead

Da dies ziemlich neu ist, habe ich nicht viel Information darüber gesehen. Hier ist mein aktueller Code:

var captureSession: AVCaptureSession? 
var stillImageOutput: AVCaptureStillImageOutput? 
var previewLayer: AVCaptureVideoPreviewLayer? 

func clickPicture() { 

    if let videoConnection = stillImageOutput?.connection(withMediaType: AVMediaTypeVideo) { 

     videoConnection.videoOrientation = .portrait 
     stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) -> Void in 

      if sampleBuffer != nil { 

       let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer) 
       let dataProvider = CGDataProvider(data: imageData!) 
       let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent) 

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

      } 

     }) 

    } 

} 

ich versucht habe, bei AVCapturePhotoCaptureDelegate zu suchen, aber ich bin mir nicht ganz sicher, wie es zu benutzen. Weiß jemand, wie man das benutzt? Vielen Dank. Hallo, es ist wirklich einfach zu bedienen AVCapturePhotoOutput

+0

Sie müssen sehen WWDC 2016 Sitzung 511 Video .. –

+0

Ohk! Also werde ich das Video anschauen und eine Antwort schreiben, wenn ich kann. Vielen Dank! – penatheboss

+0

Schauen Sie sich die [docs] (http://developer.apple.com/reference/AVFoundation/AVCapturePhotoOutput) an. – rickster

Antwort

39

zu Swift 4 aktualisiert.

Sie benötigen die AVCapturePhotoCaptureDelegate, die die CMSampleBuffer zurückgibt.

Sie können auch ein Vorschaubild, wenn Sie das sagen AVCapturePhotoSettings die previewFormat

class CameraCaptureOutput: NSObject, AVCapturePhotoCaptureDelegate { 

     let cameraOutput = AVCapturePhotoOutput() 

     func capturePhoto() { 

      let settings = AVCapturePhotoSettings() 
      let previewPixelType = settings.availablePreviewPhotoPixelFormatTypes.first! 
      let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType, 
           kCVPixelBufferWidthKey as String: 160, 
           kCVPixelBufferHeightKey as String: 160] 
      settings.previewPhotoFormat = previewFormat 
      self.cameraOutput.capturePhoto(with: settings, delegate: self) 

     } 

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {       
      if let error = error { 
       print(error.localizedDescription) 
      } 

      if let sampleBuffer = photoSampleBuffer, let previewBuffer = previewPhotoSampleBuffer, let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) { 
       print(image: UIImage(data: dataImage).size) // Your Image 
      } 

     } 

    } 

Für weitere Informationen besuchen https://developer.apple.com/reference/AVFoundation/AVCapturePhotoOutput

Hinweis: Sie haben die AVCapturePhotoOutput zum AVCaptureSession hinzufügen, bevor Sie das Bild aufnehmen . So etwas wie: session.addOutput(output), und dann: output.capturePhoto(with:settings, delegate:self) Dank @BigHeadCreations

+7

Fehler: "[AVCapturePhotoOutput capturePhotoWithSettings: delegate:] Keine aktive und aktivierte Videoverbindung". Könnten Sie bitte ein vollständiges Beispiel für iOS 10/Swift 3 geben. –

+0

@TuomasLaatikainen müssen Sie wahrscheinlich Capture-Session-Preset auf AVCaptureSessionPresetPhoto setzen –

+0

Ich habe das Video angesehen, surfte das gesamte Web, neu geschriebenen Code, iPhone geändert und kann nicht auflösen die Ausnahme "Keine aktive und aktivierte Videoverbindung" Der Apple Doc ist klassisch vage und ohne Details. Hilfe! Gibt es ein Arbeitsprojekt zu teilen? – mobibob

28

Es ist meine vollständige Umsetzung

import UIKit 
import AVFoundation 

class ViewController: UIViewController, AVCapturePhotoCaptureDelegate { 

var captureSesssion : AVCaptureSession! 
var cameraOutput : AVCapturePhotoOutput! 
var previewLayer : AVCaptureVideoPreviewLayer! 

@IBOutlet weak var capturedImage: UIImageView! 
@IBOutlet weak var previewView: UIView! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    captureSesssion = AVCaptureSession() 
    captureSesssion.sessionPreset = AVCaptureSessionPresetPhoto 
    cameraOutput = AVCapturePhotoOutput() 

    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 

    if let input = try? AVCaptureDeviceInput(device: device) { 
     if (captureSesssion.canAddInput(input)) { 
      captureSesssion.addInput(input) 
      if (captureSesssion.canAddOutput(cameraOutput)) { 
       captureSesssion.addOutput(cameraOutput) 
       previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion) 
       previewLayer.frame = previewView.bounds 
       previewView.layer.addSublayer(previewLayer) 
       captureSesssion.startRunning() 
      } 
     } else { 
      print("issue here : captureSesssion.canAddInput") 
     } 
    } else { 
     print("some problem here") 
    } 
} 

// Take picture button 
@IBAction func didPressTakePhoto(_ sender: UIButton) { 
    let settings = AVCapturePhotoSettings() 
    let previewPixelType = settings.availablePreviewPhotoPixelFormatTypes.first! 
    let previewFormat = [ 
     kCVPixelBufferPixelFormatTypeKey as String: previewPixelType, 
     kCVPixelBufferWidthKey as String: 160, 
     kCVPixelBufferHeightKey as String: 160 
    ] 
    settings.previewPhotoFormat = previewFormat 
    cameraOutput.capturePhoto(with: settings, delegate: self) 
} 

// callBack from take picture 
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) { 

    if let error = error { 
     print("error occure : \(error.localizedDescription)") 
    } 

    if let sampleBuffer = photoSampleBuffer, 
     let previewBuffer = previewPhotoSampleBuffer, 
     let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) { 
     print(UIImage(data: dataImage)?.size as Any) 

     let dataProvider = CGDataProvider(data: dataImage as CFData) 
     let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent) 
     let image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.right) 

     self.capturedImage.image = image 
    } else { 
     print("some error here") 
    } 
} 

// This method you can use somewhere you need to know camera permission state 
func askPermission() { 
    print("here") 
    let cameraPermissionStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) 

    switch cameraPermissionStatus { 
    case .authorized: 
     print("Already Authorized") 
    case .denied: 
     print("denied") 

     let alert = UIAlertController(title: "Sorry :(" , message: "But could you please grant permission for camera within device settings", preferredStyle: .alert) 
     let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil) 
     alert.addAction(action) 
     present(alert, animated: true, completion: nil) 

    case .restricted: 
     print("restricted") 
    default: 
     AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { 
      [weak self] 
      (granted :Bool) -> Void in 

      if granted == true { 
       // User granted 
       print("User granted") 
DispatchQueue.main.async(){ 
      //Do smth that you need in main thread 
      } 
      } 
      else { 
       // User Rejected 
       print("User Rejected") 

DispatchQueue.main.async(){ 
      let alert = UIAlertController(title: "WHY?" , message: "Camera it is the main feature of our application", preferredStyle: .alert) 
       let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil) 
       alert.addAction(action) 
       self?.present(alert, animated: true, completion: nil) 
      } 
      } 
     }); 
    } 
} 
} 
+3

funktioniert perfekt für mich (Test auf iPhone 7 plus) – aBikis

+0

Wie hast du den flashmode eingestellt? – coolly

+0

Unter iOS 10.0.2 arbeiten. Zum Einschalten des Flash 'settings.flashMode = .on' –

2

Die capture Delegatfunktion zu photoOutput geändert wurde. Hier ist die aktualisierte Funktion für Swift 4.