Открывать лобную и заднюю камеру в Свифте 3

Уже у меня есть сделанная и эта камера открой только лобную камеру, но я хочу создать кнопку, чтобы открывать заднюю или лобную камеру.

Это мой код:

import UIKit
import AVFoundation

class ViewController: UIViewController,
    UIImagePickerControllerDelegate,
    UINavigationControllerDelegate
{
    var captureSession = AVCaptureSession()
    var sessionOutput = AVCapturePhotoOutput()
    var sessionOutputSetting = AVCapturePhotoSettings(
        format: [AVVideoCodecKey:AVVideoCodecJPEG]
    )
    var previewLayer : AVCaptureVideoPreviewLayer?

    @IBOutlet var cameraView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        previewLayer?.frame = cameraView.bounds
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let deviceDiscoverySession = AVCaptureDeviceDiscoverySession(
            deviceTypes: [
                AVCaptureDeviceType.builtInDuoCamera,
                AVCaptureDeviceType.builtInTelephotoCamera,
                AVCaptureDeviceType.builtInWideAngleCamera
            ], mediaType: AVMediaTypeVideo,
            position: AVCaptureDevicePosition.unspecified
        )
        for device in (deviceDiscoverySession?.devices)! {
            if device.position == AVCaptureDevicePosition.back {
                do {
                    let input = try AVCaptureDeviceInput(device: device)
                    if captureSession.canAddInput(input) {
                        captureSession.addInput(input)

                        if captureSession.canAddOutput(sessionOutput) {
                            captureSession.addOutput(sessionOutput)
                            previewLayer = AVCaptureVideoPreviewLayer(
                                session: captureSession
                            )
                            previewLayer?.videoGravity =
                                AVLayerVideoGravityResizeAspectFill
                            previewLayer?.connection.videoOrientation =
                                AVCaptureVideoOrientation.portrait
                            cameraView.layer.addSublayer(previewLayer!)  
                        }
                    }
                } catch {
                    print("Error")
                }
            }
        }
        captureSession.startRunning()
    }
}

⚠️ ПРОБЛЕМА С ОРИЕНТАЦИЕЙ В ЛОБНОЙ ПАЛАТЕ ⚠️

У меня есть проблема с этим. Ориентация фотографии, взятой в лобной камере кажется неправильной.

Такой появись в виде перед тем, как снимать с лобной камерой

introducir la descripción de la imagen aquí

И я схватил, когда я снимаю с лобной камерой, кажется, что применяется ориентация зеркала

introducir la descripción de la imagen aquí

В задней камере не существует эта ошибка, все течет с нормальностью

Поскольку я могу решать это, @Wilson очень любезно он дал мне возможное решение, которое в настоящее время составляет часть моего кода, но кажется, что оно не функционирует. Я продолжаю иметь ту же ошибку.

Какое-то решение?

2
задан 06.02.2017, 00:32
1 ответ

Форма, которая hize, добавляя кнопку в виде и потом присоединяя IBAction к так называемой кнопке changeCameraPosition для потом внутри этого метода, выполнила 3 других метода:

  • getDesiredCameraPosition: который получит положение из камеры уже был бы покрывалом алтаря или задней.
  • getCamera: на основании положения камеры, которую мы переместим его в эту функцию, он получит снабди ссылками в для полуторной кровати, которая интересует нас
  • setCamera: Имея эта снабди ссылками cameraAvailable, он dicemos в iOS, что показал эту ссылку в физической камере, выполняя эту функцию setCamera.

Code:

  @IBAction func changeCameraPosition() {
    let desiredCameraPosition = getDesiredCameraPosition(by: currentVideoInput)

    let cameraAvailable = getCamera(byPosition: desiredCameraPosition)

    setCamera(with: cameraAvailable)
  }

Source code:

import UIKit
import AVFoundation

class ViewController: UIViewController,
  UIImagePickerControllerDelegate,
UINavigationControllerDelegate {

  var captureSession = AVCaptureSession()
  var sessionOutput = AVCapturePhotoOutput()
  var sessionOutputSetting = AVCapturePhotoSettings(
    format: [AVVideoCodecKey:AVVideoCodecJPEG]
  )
  var previewLayer : AVCaptureVideoPreviewLayer?
  @IBOutlet var cameraView: UIView!

  // added
  var currentVideoInput: AVCaptureDeviceInput?

  @IBAction func changeCameraPosition() {
    let desiredCameraPosition = getDesiredCameraPosition(by: currentVideoInput)

    let cameraAvailable = getCamera(byPosition: desiredCameraPosition)

    setCamera(with: cameraAvailable)
  }

  // added
  func getDesiredCameraPosition(by videoInput:AVCaptureDeviceInput?) -> AVCaptureDevicePosition {
    let currentCameraPosition = videoInput?.device.position
    var desiredCameraPosition = AVCaptureDevicePosition.back

    if currentCameraPosition == .front {
      desiredCameraPosition = .back
    } else if currentCameraPosition == .back {
      desiredCameraPosition = .front
    }

    return desiredCameraPosition
  }

  // added
  func setCamera(with camera: AVCaptureDevice?) {
    if let cameraAvailable = camera {
      let videoInput = try? AVCaptureDeviceInput(device: cameraAvailable)

      if let videoInput = videoInput {
        self.captureSession.beginConfiguration()
        self.captureSession.removeInput(self.currentVideoInput)

        if self.captureSession.canAddInput(videoInput) {
          self.captureSession.addInput(videoInput)
          self.currentVideoInput = videoInput
        } else {
          self.captureSession.addInput(self.currentVideoInput)
        }

        self.captureSession.commitConfiguration()
      }
    }
  }

  // added
  func getCamera(byPosition position: AVCaptureDevicePosition) -> AVCaptureDevice? {
    let deviceTypes: [AVCaptureDeviceType] = [.builtInDuoCamera, .builtInTelephotoCamera,.builtInWideAngleCamera]
    let session = AVCaptureDeviceDiscoverySession(
                        deviceTypes: deviceTypes,
                        mediaType: AVMediaTypeVideo,
                        position: position
                  )

    if let session = session {
      if let devices = session.devices {
        for device in devices {
          if device.position == position {
            return device
          }
        }
      }
    }

    return nil
  }




  override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
  }
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    previewLayer?.frame = cameraView.bounds
  }
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let deviceDiscoverySession = AVCaptureDeviceDiscoverySession(
      deviceTypes: [
        AVCaptureDeviceType.builtInDuoCamera,
        AVCaptureDeviceType.builtInTelephotoCamera,
        AVCaptureDeviceType.builtInWideAngleCamera
      ], mediaType: AVMediaTypeVideo,
         position: AVCaptureDevicePosition.unspecified
    )
    for device in (deviceDiscoverySession?.devices)! {
      if device.position == AVCaptureDevicePosition.back {
        do {
          let input = try AVCaptureDeviceInput(device: device)
          if captureSession.canAddInput(input) {
            captureSession.addInput(input)

            // added
            currentVideoInput = input

            if captureSession.canAddOutput(sessionOutput) {
              captureSession.addOutput(sessionOutput)
              previewLayer = AVCaptureVideoPreviewLayer(
                session: captureSession
              )
              previewLayer?.videoGravity =
              AVLayerVideoGravityResizeAspectFill
              previewLayer?.connection.videoOrientation =
                AVCaptureVideoOrientation.portrait
              cameraView.layer.addSublayer(previewLayer!)
            }
          }
        } catch {
          print("Error")
        }
      }
    }
    captureSession.startRunning()
  }
}

UPDATE (take picture functionality):

extension ViewController: AVCapturePhotoCaptureDelegate {

  @IBAction func takePictureButtonTouched() {
    captureImage()
  }


  func captureImage(){
    let connection = self.sessionOutput.connection(withMediaType: AVMediaTypeVideo)

    if let connection = connection, connection.isVideoOrientationSupported {
      connection.videoOrientation = .portrait
    }

    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.sessionOutput.capturePhoto(with: settings, delegate: self)
  }

  func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
    if
      let sampleBuffer = photoSampleBuffer,
      let previewBuffer = previewPhotoSampleBuffer,
      let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {



      var capturedImage = UIImage(data: dataImage)

      let cameraPosition = currentVideoInput?.device.position

      // si la camara es la frontal,
      // hacemos un flipping a la imagen
      if let image = capturedImage,
         cameraPosition == .front {

        capturedImage = UIImage(
          cgImage: image.cgImage!,
          scale: image.scale,
          orientation: UIImageOrientation.leftMirrored
        )

      }

      DispatchQueue.main.async {
        print(capturedImage)
      }
    }
  }
}

Сообщи мне, если ты нуждаешься в каком-то выяснении, я надеюсь, что он подает тебя, Привет compañero!

2
ответ дан 24.11.2019, 11:23
  • 1
    Совершенная твой ответ, я sirvió много, но я хотел бы знать, как я могу арестовывать фотографию, так как у меня есть проблемы с orientació n этой. Я gustarí которому он будет предоставлять какую-то solució n рџ‘Њ – Sebastián Varella Gmz 05.02.2017, 04:19
  • 2
    не problem Себастьян, я обновил мой раствор включая задержание фотографии, хотя этот update не имеет ничего общего с формулируемым вопросом, я поместил ее в конце концов, если у тебя есть какой-то вопрос относительно части задержания фотографии, я предлагаю тебе создавать другой вопрос в stackoverflow и...... не забывать отмечать ответ как стоившая ;) – Wilson 05.02.2017, 15:23
  • 3
    Большое спасибо @Wilson, большая работа рџ ™Њ – Sebastián Varella Gmz 05.02.2017, 19:06
  • 4
    нет, потому что, спасибо! – Wilson 05.02.2017, 20:59
  • 5
    Большое спасибо @Wilson, решенная проблема рџ‘Њ – Sebastián Varella Gmz 06.02.2017, 22:08