iOS10とswift3でカメラアプリを実装

概要

iOS10カスタムカメラ – Swift 3 on @Qiita
について、自分なりに解釈し、一行ずつ理解しながらコードを整理した。

OSはiOS10を、言語はswift3を利用。アプリを起動するとカメラが立ち上がり、撮影した結果をUIImageで表示するだけの最小限のカメラアプリを実装した。

plistの設定及びストーリーボードの設定についてはリンク先と同様なので割愛

前提

要素 バージョン
xcode 8.2.1
iOS 10.2

ソースコード(swift)

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCapturePhotoCaptureDelegate {

  /* カメラを表示するビュー */
  @IBOutlet weak var cameraView: UIView!
  
  /* キャプチャーセッション */
  var captureSesssion: AVCaptureSession!
  
  /* カメラ */
  var stillImageOutput: AVCapturePhotoOutput?
  
  /* プレビューレイヤー */
  var previewLayer: AVCaptureVideoPreviewLayer?
  
  /* 撮影 */
  @IBAction func takeIt(_ sender: Any) {
    
    /* 撮影単位の設定情報を生成 */
    let settingsForMonitoring = AVCapturePhotoSettings()
    
    /* フラッシュの有無(オート) */
    settingsForMonitoring.flashMode = .auto
    
    /* 手ぶれ補正を有効にする(?) */
    settingsForMonitoring.isAutoStillImageStabilizationEnabled = true
    settingsForMonitoring.isHighResolutionPhotoEnabled = false
    
    /* シャッターを切る */
    stillImageOutput?.capturePhoto(with: settingsForMonitoring, delegate: self)
    
  }
  
  /* アプリ起動直前に初期化 */
  override func viewWillAppear(_ animated: Bool) {
    
    /* カメラの初期化 */
    captureSesssion = AVCaptureSession()
    stillImageOutput = AVCapturePhotoOutput()
    
    /* カメラの解像度を1920x1080に設定する */
    captureSesssion.sessionPreset = AVCaptureSessionPreset1920x1080;
    
    /* デバイスを設定(デフォルトのビデオデバイスを選択) */
    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo);
    
    do {
      
      /* デバイスを取得 */
      let input = try AVCaptureDeviceInput(device: device)
      
      /* デバイスにセッションを入力可能かを検証 */
      if (captureSesssion.canAddInput(input)) {
        
        /* デバイスをセッションに入力 */
        captureSesssion.addInput(input)
        
        /* デバイスを出力可能かを検証 */
        if (captureSesssion.canAddOutput(stillImageOutput)) {
        
          /* デバイスを出力 */
          captureSesssion.addOutput(stillImageOutput)
          
          /* カメラを起動 */
          captureSesssion.startRunning()
          
          /* プレビューレイヤーを初期化 */
          previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
          
          /* レイヤーの引き伸ばし設定(アスペクトフィット) */
          previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
          
          /* カメラの向きを設定(縦向き) */
          previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
          
          /* サブビューにプレビューレイヤーを重ねる */
          cameraView.layer.addSublayer(previewLayer!)
          
          /* サブビュー内のプレビューレイヤーの表示位置を調整 */
          previewLayer?.position = CGPoint(x: self.cameraView.frame.width / 2, y: self.cameraView.frame.height / 2)
          previewLayer?.bounds = cameraView.frame
          
        }
      }
    } catch {
      print(error);
    }
  }
  
  /* 写真が撮影された */
  func capture(
    _ captureOutput: AVCapturePhotoOutput,
    didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?,
    previewPhotoSampleBuffer: CMSampleBuffer?,
    resolvedSettings: AVCaptureResolvedPhotoSettings,
    bracketSettings: AVCaptureBracketedStillImageSettings?,
    error: Error?) {
    
    /* unwrapし、nilじゃないことを検証 */
    if let photoSampleBuffer = photoSampleBuffer {
    
      /* 撮影データをJPEGに変換 */
      let photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)
      
      /* JPEG画像をUIImageに変換 */
      let image = UIImage(data: photoData!)
      
      /* UIImageをフォトライブラリに保存 */
      UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
      
      print("hoghog");
      
    }
  }
}

※ シンタックスハイライトは、swiftが対応していなかったので便宜上JavaScriptを設定

実行結果

  • Buttonをタップで撮影
  • 撮影された写真はメディアライブラリに保存

参考

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です