[AVFoundation] UIDevice Orientation と AVCaptureVideoOrientation

AVFoundation

AVFoundationを使ったプレビューの実装に AVCaptureVideoPreviewLayer 使うと、デバイスの回転についても自分で調整しないといけません。その方法を説明します。

デバイスの向きは、UIDeviceOrientation

デバイスの向きについては、UIDeviceOrientation として簡単に取得することができます。

デバイスの向き取得

let deviceOrientatoin = UIDevice.current.orientation

返り値のタイプは、UIDeviceOrientation です。

以下の値があります。

unknown
判定できない時に返る値
portrait
縦の向きで、ホームボタンが下側の時に返る値
portraitUpsideDown
縦の向きですが、portrait とは、上下が逆で、ホームボタンが上側にあるときに返る値
landscapeLeft
横の向きで、ホームボタンが右側にあるときに返る値
landscapeRight
横の向きで、ホームボタンが左側にあるときに返る値

ビデオの向きは、AVCaptureVideoOrientation

ビデオ撮影時プレビューの向きについては、AVCaptureVideoOrientation として簡単に設定することができます。

プレビューの向き設定

previewLayer.connection?.videoOrientation = .portrait

設定値のタイプは、AVCaptureVideoOrientation です。

以下の値があります。

portrait
縦の向きで、上側が上にある時に返る値
portraitUpsideDown
縦の向きで、上側が上にある時に返る値
landscapeRight
横の向きで、上側が左にある時に返る値
landscapeLeft
横の向きで、上側が右にある時に返る値

落とし穴:UIDeviceOrientation と AVCaptureVideoOrientation は、同じ?

ぱっと見は、同じに見えますよね。でも違うんです・・・・

そのまま代入できませんし、実は、landscapeRight と landscapeLeft の位置付けが逆になっています。

よくよく説明を見ると、逆であることに気づけます。(実際にやっても、期待する方向と逆になります)

例えば、こんな感じで対応づけて設定すると、イメージ通りの向きにプレビューが表示されます。

プレビューの向き設定

    func updatePreviewOrientation() {
        switch UIDevice.current.orientation {
        case .portrait:
            self.previewLayer.connection?.videoOrientation = .portrait
        case .portraitUpsideDown:
            self.previewLayer.connection?.videoOrientation = .portraitUpsideDown
        case .landscapeLeft:
            self.previewLayer.connection?.videoOrientation = .landscapeRight     // !!! left -> right !!!
        case .landscapeRight:
            self.previewLayer.connection?.videoOrientation = .landscapeLeft      // !!! right -> left !!!
        default:
            self.previewLayer.connection?.videoOrientation = .portrait           // unknown ....
        }
        return
    }

まとめ:UIDeviceOrientation と AVCaptureVideoOrientation の対応づけは、工夫が必要

デバイスの回転をプレビューに反映させるのは、previewLayer.connection?.videoOrientation というように簡単にできます。

ただし、UIDeviceから取得できる情報から AVCaptureVideoOrientation を設定する時には、以下の点に気をつける必要があります。

  • UIDeviceOrientation にだけ、unknown がある
  • portrait, portraitUpsideDown は、同じ意味を持つ
  • landscapeRight と landscapeLeft は、UIDeviceOrientation と AVCaptureVideoOrientation では、逆の意味を持つ

説明は以上です。

コメントを残す

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