Skip to content
Permalink
Browse files

Merge pull request #12 from CameraKit/fix/orientation

Preview/image/video orientation fix
  • Loading branch information...
adrianmateoaea24 committed Feb 27, 2019
2 parents 22c9259 + c8895f0 commit b785bbc7e4f2e0d8f783005c45500abad6d6f66e
@@ -109,6 +109,14 @@ extension CKFSession.FlashMode {
let settings = AVCapturePhotoSettings()
settings.flashMode = self.flashMode.captureFlashMode

if let connection = self.photoOutput.connection(with: .video) {
if self.resolution.width > 0, self.resolution.height > 0 {
connection.videoOrientation = .portrait
} else {
connection.videoOrientation = UIDevice.current.orientation.videoOrientation
}
}

self.photoOutput.capturePhoto(with: settings, delegate: self)
}

@@ -224,7 +232,7 @@ extension CKFSession.FlashMode {

if
self.resolution.width > 0, self.resolution.height > 0,
let transformedImage = CKFUtils.cropAndScale(image, width: Int(self.resolution.width), height: Int(self.resolution.height))
let transformedImage = CKUtils.cropAndScale(image, width: Int(self.resolution.width), height: Int(self.resolution.height), orientation: UIDevice.current.orientation, mirrored: self.cameraPosition == .front)
{
self.captureCallback(transformedImage, resolvedSettings)
return
@@ -60,6 +60,14 @@ import AVFoundation
}
}

@objc public var autorotate: Bool = false {
didSet {
if !self.autorotate {
self.previewLayer?.connection?.videoOrientation = .portrait
}
}
}

@objc public override init(frame: CGRect) {
super.init(frame: frame)
self.setupView()
@@ -102,5 +110,9 @@ import AVFoundation
super.layoutSubviews()
self.previewLayer?.frame = self.bounds
self.gridView?.frame = self.bounds

if self.autorotate {
self.previewLayer?.connection?.videoOrientation = UIDevice.current.orientation.videoOrientation
}
}
}
@@ -8,6 +8,22 @@
import AVFoundation

public extension UIDeviceOrientation {

var videoOrientation: AVCaptureVideoOrientation {
switch UIDevice.current.orientation {
case .portraitUpsideDown:
return .portraitUpsideDown
case .landscapeLeft:
return .landscapeRight
case .landscapeRight:
return .landscapeLeft
default:
return .portrait
}
}
}

private extension CKFSession.DeviceType {

var captureDeviceType: AVCaptureDevice.DeviceType {
@@ -8,9 +8,37 @@
import UIKit

@objc public class CKFUtils: NSObject {
private extension UIDeviceOrientation {
var imageOrientation: UIImageOrientation {
switch self {
case .portraitUpsideDown:
return .left
case .landscapeLeft:
return .up
case .landscapeRight:
return .down
default:
return .right
}
}

@objc public static func cropAndScale(_ image: UIImage, width: Int, height: Int) -> UIImage? {
var imageOrientationMirrored: UIImageOrientation {
switch self {
case .portraitUpsideDown:
return .left
case .landscapeLeft:
return .down
case .landscapeRight:
return .up
default:
return .right
}
}
}

@objc public class CKUtils: NSObject {

@objc public static func cropAndScale(_ image: UIImage, width: Int, height: Int, orientation: UIDeviceOrientation, mirrored: Bool) -> UIImage? {
let fromRect = CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width)
var toRect = CGRect(x: 0, y: 0, width: height, height: width)

@@ -40,7 +68,8 @@ import UIKit
guard let finalCgImage = context.makeImage() else {
return nil
}

return UIImage(cgImage: finalCgImage, scale: 1.0, orientation: .right)

let orientation = mirrored ? orientation.imageOrientationMirrored : orientation.imageOrientation
return UIImage(cgImage: finalCgImage, scale: 1.0, orientation: orientation)
}
}
@@ -120,6 +120,10 @@ extension CKFSession.FlashMode {
return fileUrl
}()

if let connection = self.movieOutput.connection(with: .video) {
connection.videoOrientation = UIDevice.current.orientation.videoOrientation
}

self.movieOutput.startRecording(to: fileUrl, recordingDelegate: self)
}

@@ -23,14 +23,13 @@
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WrD-in-aex" customClass="CKFPreviewView" customModule="CameraKit">
<rect key="frame" x="0.0" y="0.5" width="320" height="427"/>
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" secondItem="WrD-in-aex" secondAttribute="height" multiplier="1:1" priority="250" id="Rz4-OH-s48"/>
<constraint firstAttribute="width" secondItem="WrD-in-aex" secondAttribute="height" multiplier="3:4" priority="750" id="jew-Fn-3S0"/>
</constraints>
</view>
<visualEffectView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Fmb-ws-sF8">
<rect key="frame" x="143.5" y="8.5" width="33" height="19"/>
<rect key="frame" x="143.5" y="8" width="33" height="19"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="LW1-hd-LLC">
<rect key="frame" x="0.0" y="0.0" width="33" height="19"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -61,9 +60,9 @@
<constraints>
<constraint firstAttribute="trailing" secondItem="WrD-in-aex" secondAttribute="trailing" id="1Zs-Th-7wt"/>
<constraint firstItem="WrD-in-aex" firstAttribute="leading" secondItem="0UD-h8-yNR" secondAttribute="leading" id="Gfy-jQ-1k9"/>
<constraint firstItem="Fmb-ws-sF8" firstAttribute="top" secondItem="0UD-h8-yNR" secondAttribute="top" constant="8" id="Ld9-OC-Olo"/>
<constraint firstItem="Fmb-ws-sF8" firstAttribute="centerX" secondItem="0UD-h8-yNR" secondAttribute="centerX" id="RbR-jl-KLK"/>
<constraint firstItem="WrD-in-aex" firstAttribute="centerY" secondItem="0UD-h8-yNR" secondAttribute="centerY" id="XNk-AI-peP"/>
<constraint firstItem="Fmb-ws-sF8" firstAttribute="top" secondItem="WrD-in-aex" secondAttribute="top" constant="8" id="qdK-o4-1Y6"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cs9-hk-xYz">
@@ -568,7 +567,6 @@
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aD4-vr-3Ay" customClass="CKFPreviewView" customModule="CameraKit">
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<visualEffectView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="geg-uJ-o6S">
<rect key="frame" x="143.5" y="8" width="33" height="19"/>
@@ -43,6 +43,8 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
@@ -125,6 +125,7 @@ class PhotoViewController: UIViewController, CKFSessionDelegate {
session.resolution = CGSize(width: 3024, height: 4032)
session.delegate = self

self.previewView.autorotate = true
self.previewView.session = session
self.previewView.previewLayer?.videoGravity = .resizeAspectFill
}
@@ -106,6 +106,7 @@ class VideoViewController: UIViewController, CKFSessionDelegate {
let session = CKFVideoSession()
session.delegate = self

self.previewView.autorotate = true
self.previewView.session = session
self.previewView.previewLayer?.videoGravity = .resizeAspectFill
}
@@ -21,6 +21,7 @@ With CameraKit you are able to effortlessly do the following:
- ✅ Image and video capture seamlessly working with the same preview session.
- ✅ Automatic system permission handling.
- ✅ Automatic preview scaling.
- ✅ Automatic preview/image/video output orientation handling.
- 📷 Ability to set a custom resolution for capturing photos.
- 📹 Ability to set resolution/frame rate for capturing videos.
- 👱‍ Built-in face detection.

0 comments on commit b785bbc

Please sign in to comment.
You can’t perform that action at this time.