2016-08-26 14 views
10

カメラビューをView Controllerに配置しようとしています。AVCaptureStillImageOutputとSwiftのAVCapturePhotoOutput 3

AVFoundationを先頭に、またUIImagePickerControllerDelegateUINavigationControllerDelegateクラスをインポートしました。

しかし、私がAVCaptureStillImageOutputを使用しようとすると、XcodeはiOS10で廃止予定だったと私に知らせ、AVCapturePhotoOutputを使用するべきです。それは完全に問題ありませんが、stillImageOutput.outputSettingsに電話するとすぐに.outputSettingsは利用できません。したがって、私はそれを動作させるためにAVAVCaptureStillImageOutputを使用する必要がありますが、この機能はiOS10では廃止されたため、複数の警告があります。

私は検索して検索しましたが、本当に解決策を見つけることができませんでした。私は本当にあなたの助けに感謝します。私はどんな説明もすばらしくなるように学んでいます!コードは以下のとおりです。廃止さ

import UIKit 
import AVFoundation 

class CameraView: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 

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

    @IBOutlet var cameraView: UIView! 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
     captureSession = AVCaptureSession() 
     captureSession?.sessionPreset = AVCaptureSessionPreset1920x1080 

     var backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 
     var error : NSError? 

     do { 
      var input = try! AVCaptureDeviceInput (device: backCamera) 
      if (error == nil && captureSession?.canAddInput(input) != nil) { 

       captureSession?.addInput(input) 

       stillImageOutput = AVCaptureStillImageOutput() 
       stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] 

       if (captureSession?.canAddOutput(stillImageOutput) != nil) { 
        captureSession?.addOutput(stillImageOutput) 

        previewLayer = AVCaptureVideoPreviewLayer (session: captureSession) 
        previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect 
        previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait 
        cameraView.layer.addSublayer(previewLayer!) 
        captureSession?.startRunning() 
       } 
      } 
     } catch { 

     } 
    } 
} 
+0

は、あなたがあなたのコードの一部を追加したい場合がありますがあります。 –

答えて

3

AVCaptureStillImageOutputあなたはiOSの10でそれを使用し続けることができることを意味しますが、:

  • Appleは、それが利用可能に滞在されますどのくらいのiOS 10過去に何ら約束するものではありません。
  • 新しいハードウェアとソフトウェアの機能がiOS 10以降で追加されると、それらのすべてにアクセスすることはできません。たとえば、となります。幅広い色の場合はAVCaptureStillImageOutputに設定しますが、AVCapturePhotoOutputの場合は広い色を使用する方がはるかに簡単です。 RAWキャプチャやライブ写真では、AVCapturePhotoOutputは唯一のゲームです。

あなたは非推奨にもかかわらず、幸せに進むなら、あなたの問題はoutputSettingsが削除されていることではありません - it's still there。ベータ6以降の注意すべき

何か(それはここでの問題ではないことが判明しても):明示的なキーと値の型なしNSDictionaryを使用するAPIは[AnyHashable: Any]としてスウィフト3に来て、財団やCoreFoundationのタイプのあなたディクショナリで使用できるかもしれないが、もはやSwiftタイプに暗黙的にブリッジされていません。 (other questions about beta 6 dictionary conversionsの中には正しい方向を指し示すものもあります)

しかし、outputSettingsの設定ではコンパイルエラーが発生しません。あなたの完全なコード内かどうか、その行のために不可欠な部品にそれを減らすことによって:

var stillImageOutput : AVCaptureStillImageOutput? 
stillImageOutput = AVCaptureStillImageOutput() 
stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] 

...私が見る唯一の警告は、非推奨としています。

+0

ありがとうございました! –

8

私の完全な実装

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) 
     } 
     } 
    }); 
} 
} 
} 
+0

お返事ありがとうございました。 :) –