さかもっちの技術メモ

色々と技術的なことを記載します。

iOS 背景をカメラの映像にしてみる

iOSアプリで背景にカメラの映像を出来るか調べてみました。

調べていると、swiftのバージョンが上がると書き方が変わることが多いようなので、参考としてバージョンを記載。

  • Xcode:8.3.3
  • swift:3.1
  • iOS:10.3.3 (動作確認したiphone 6 のバージョン) 

UIViewを1つ画面いっぱいに配置してそれにカメラの映像を入力として渡します。


ViewController.swift

import UIKit

import AVFoundation


class ViewController: UIViewController {

  var mySession : AVCaptureSession!
  var myDevice : AVCaptureDevice!
  var myImageOutput : AVCapturePhotoOutput!

  @IBOutlet weak var myView: UIView!

  override func viewDidLoad() {
    super.viewDidLoad()
    // セッションの作成
    mySession = AVCaptureSession()
    // カメラデバイスの取得
    if #available(iOS 10.0, *) {

      let discoverySession = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .back)

      for device in discoverySession!.devices {
        myDevice = device
      }
    } else {
      myDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
    }
    myView.backgroundColor = UIColor.clear

    do {
      // バックカメラからVideoInputを取得
      let videoInput = try AVCaptureDeviceInput.init(device: myDevice)
      // セッションに追加
      mySession.addInput(videoInput)
      // 画像を表示するレイヤーを生成
      let myVideoLayer = AVCaptureVideoPreviewLayer(session: mySession)
      myVideoLayer?.frame = myView.bounds
      myVideoLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill

      // Viewに追加
      myView.layer.addSublayer(myVideoLayer!)

      mySession.startRunning()
    } catch {
      return
    }
  }
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  override var shouldAutorotate: Bool {
    get {
      return false
    }
  }
}

ここでハマったのは、「AVCaptureDeviceType.builtInWideAngleCamera」。

「AVCaptureDeviceType.builtInDualCamera」を指定して、iphone 6 で動作確認したらうまく動きませんでした。
iphone 6 にはデュアルカメラが搭載されていないから。。。
これに数時間費やしてしまいました。

ネットから集めたコードをコピペして使うときは、コードの意味をきちんと理解しましょうと改めて感じた限りです。