2017-02-16 2 views
3

У меня есть очень простая камера AVFoundation, у которой есть captureButton, который сделает снимок и отправит его на secondCameraController для его отображения. Моя проблема в том, что существует много изъянов iOS 10, и я не уверен, как я добавляю вспышку, когда нажимаю captureButton. Любая помощь будет высоко оценена. Мой код ниже. Спасибо вам, ребята.Swift 3: Как включить вспышку на пользовательской камере AVFoundation?

class CameraController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate { 

let captureSession = AVCaptureSession() 
var previewLayer: CALayer! 

var captureDevice: AVCaptureDevice! 

var takePhoto: Bool = false 

override func viewDidLoad() { 
    super.viewDidLoad() 
    view.backgroundColor = .white 
} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
    prepareCamera() 
} 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 
    navigationController?.setNavigationBarHidden(true, animated: true) 
} 

let cameraView: UIView = { 
    let view = UIView() 
    view.backgroundColor = .red 
    return view 
}() 

func prepareCamera() { 
    captureSession.sessionPreset = AVCaptureSessionPresetPhoto 

    if let availableDevices = AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .back).devices { 

     captureDevice = availableDevices.first 
     beginSession() 
    } 
} 

func beginSession() { 
    do { 
     let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice) 

     captureSession.addInput(captureDeviceInput) 

    } catch { 

     print(error.localizedDescription) 
    } 

    if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) { 
     self.previewLayer = previewLayer 
     self.view.layer.addSublayer(self.previewLayer) 
     self.previewLayer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height) 
     previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 

     self.view.addSubview(captureButton) 

     let width: CGFloat = 85 
     captureButton.frame = CGRect(x: (previewLayer.frame.width/2) - width/2, y: (previewLayer.frame.height) - width - 25, width: width, height: 85) 

     captureSession.startRunning() 

     let dataOutput = AVCaptureVideoDataOutput() 
     dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString): NSNumber(value: kCVPixelFormatType_32BGRA)] 

     dataOutput.alwaysDiscardsLateVideoFrames = true 

     if captureSession.canAddOutput(dataOutput) { 
      captureSession.addOutput(dataOutput) 
     } 

     captureSession.commitConfiguration() 

     let queue = DispatchQueue(label: "com.cheekylabsltd.camera") 
     dataOutput.setSampleBufferDelegate(self, queue: queue) 
    } 
} 

func handleCapture() { 
    takePhoto = true 
} 

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 

    if takePhoto { 
     takePhoto = false 

     if let image = self.getImageFromSampleBuffer(buffer: sampleBuffer) { 
      let secondController = SecondCameraController() 
      secondController.takenPhoto = image 

      DispatchQueue.main.async { 
       self.present(secondController, animated: true, completion: { 
        self.stopCaptureSession() 
       }) 
      } 
     } 
    } 
} 

func getImageFromSampleBuffer(buffer: CMSampleBuffer) -> UIImage? { 

    if let pixelBuffer = CMSampleBufferGetImageBuffer(buffer) { 
     let ciImage = CIImage(cvPixelBuffer: pixelBuffer) 
     let context = CIContext() 

     let imageRect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer)) 

     if let image = context.createCGImage(ciImage, from: imageRect) { 
      return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .right) 
     } 
    } 

    return nil 
} 

func stopCaptureSession() { 
    self.captureSession.stopRunning() 

    if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] { 
     for input in inputs { 
      self.captureSession.removeInput(input) 
     } 
    } 
} 

lazy var captureButton: UIButton = { 
    let button = UIButton(type: .system) 
    button.backgroundColor = .white 
    button.layer.cornerRadius = 42.5 
    button.clipsToBounds = true 
    button.alpha = 0.40 
    button.layer.borderWidth = 4 
    button.layer.borderColor = greenColor.cgColor 
    button.addTarget(self, action: #selector(handleCapture), for: .touchUpInside) 
    return button 
}() 
} 
+0

Проверка компании Apple [Фотоцентр] (https://developer.apple.com/library/prerelease/content/documentation/AudioVideo/Conceptual/PhotoCaptureGuide/index.html#//apple_ref/doc/uid/TP40017511) руководство. – rickster

+0

@ rickster Черт, я не ожидал, что много информации. Благодаря! Лучшие Мужчины. – Jimmy

ответ

5

Попробуйте этот код: Swift v3.0

private func flashOn(device:AVCaptureDevice) 
    { 
     do{ 
      if (device.hasTorch) 
      { 
       try device.lockForConfiguration() 
       device.torchMode = .on 
       device.flashMode = .on 
       device.unlockForConfiguration() 
      } 
     }catch{ 
      //DISABEL FLASH BUTTON HERE IF ERROR 
      print("Device tourch Flash Error "); 
     } 
    } 

// ДЛЯ FLASH OFF КОД

private func flashOff(device:AVCaptureDevice) 
    { 
     do{ 
      if (device.hasTorch){ 
       try device.lockForConfiguration() 
       device.torchMode = .off 
       device.flashMode = .off 
       device.unlockForConfiguration() 
      } 
     }catch{ 
      //DISABEL FLASH BUTTON HERE IF ERROR 
      print("Device tourch Flash Error "); 
     } 
    } 

// МЕТОД

// частная пусть сессия = AVCaptureSession()

//MARK: FLASH UITLITY METHODS 
    func toggleFlash() { 
     var device : AVCaptureDevice! 

     if #available(iOS 10.0, *) { 
      let videoDeviceDiscoverySession = AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera, .builtInDuoCamera], mediaType: AVMediaTypeVideo, position: .unspecified)! 
      let devices = videoDeviceDiscoverySession.devices! 
      device = devices.first! 

     } else { 
      // Fallback on earlier versions 
      device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 
     } 

     if ((device as AnyObject).hasMediaType(AVMediaTypeVideo)) 
     { 
      if (device.hasTorch) 
      { 
       self.session.beginConfiguration() 
       //self.objOverlayView.disableCenterCameraBtn(); 
       if device.isTorchActive == false { 
        self.flashOn(device: device) 
       } else { 
        self.flashOff(device: device); 
       } 
       //self.objOverlayView.enableCenterCameraBtn(); 
       self.session.commitConfiguration() 
      } 
     } 
    } 
0

Swift 4

Таким образом, есть два различных поведения на выбор в AVFoundation. Одним из них будет переключатель резака устройства захвата. Подключите torchSwitch действие к некоторому виду и обязательно измените CameraManager.shared.backDevice к вашему экземпляру переднего или заднего устройства, которое обеспечивает текущий вход.

@IBAction func torchSwitch(_ sender: Any) { 
    guard let device = CameraManager.shared.backDevice else { return } 
    guard device.isTorchAvailable else { return } 
    do { 
     try device.lockForConfiguration() 
     device.torchMode = device.torchMode ? .off : .on 
     if device.torchMode == .on { 
     try device.setTorchModeOn(level: 0.7) 
     } 
    } catch { 
     debugPrint(error) 
    } 
    } 

AVFoundation имеет осуждается device.flashMode

Теперь, чтобы установить вспышку, объявить переменную на камеру или ВХ. Значение здесь будет по умолчанию.

var flash: AVCaptureFlashMode = .off 

Подключите данное действие какой-то точки зрения

@IBAction func torchSwitch(_ sender: Any) { flash = flash ? .off : .on } 

Затем, когда вы хотите, чтобы захватить изображение, используйте AVCapturePhotoOutput и подготовить настройки фото. stillCameraOutput - это пример AVCapturePhotoOutput.

let settings = AVCapturePhotoSettings() 
    settings.flashMode = flash 
    stillCameraOutput.capturePhoto(with: settings, delegate: self) 
Смежные вопросы