Я пишу этот код на Swift на случай, если кому-то может понадобиться.
Шаг 1: Генерация уведомлений об ориентации (в вашем viewDidLoad
)
UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("deviceOrientationDidChange:"), name: UIDeviceOrientationDidChangeNotification, object: nil)
Шаг 2: Сфотографируйся. Здесь мы поменяем ориентацию videoConnection
. В AVFoundation есть небольшое изменение в ориентации, особенно для альбомной ориентации. Так что мы просто поменяемся. Например, мы изменим с LandscapeRight
на LandscapeLeft
и наоборот
func takePicture() {
if let videoConnection = stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo) {
var newOrientation: AVCaptureVideoOrientation?
switch (UIDevice.currentDevice().orientation) {
case .Portrait:
newOrientation = .Portrait
break
case .PortraitUpsideDown:
newOrientation = .PortraitUpsideDown
break
case .LandscapeLeft:
newOrientation = .LandscapeRight
break
case .LandscapeRight:
newOrientation = .LandscapeLeft
break
default :
newOrientation = .Portrait
break
}
videoConnection.videoOrientation = newOrientation!
stillImageOutput!.captureStillImageAsynchronouslyFromConnection(videoConnection) {
(imageDataSampleBuffer, error) -> Void in
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
dispatch_async(dispatch_get_main_queue()) {
let image = UIImage(data: imageData!)!
let portraitImage = image.fixOrientation()
}
}
}
}
}
ПРИМЕЧАНИЕ. Обратите внимание на новое значение ориентации для альбомной ориентации. Это как раз наоборот. (Это виновник :: UHHHH)
Шаг 3: исправить ориентацию (расширение UIImage)
extension UIImage {
func fixOrientation() -> UIImage {
if imageOrientation == UIImageOrientation.Up {
return self
}
var transform: CGAffineTransform = CGAffineTransformIdentity
switch imageOrientation {
case UIImageOrientation.Down, UIImageOrientation.DownMirrored:
transform = CGAffineTransformTranslate(transform, size.width, size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
break
case UIImageOrientation.Left, UIImageOrientation.LeftMirrored:
transform = CGAffineTransformTranslate(transform, size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
break
case UIImageOrientation.Right, UIImageOrientation.RightMirrored:
transform = CGAffineTransformTranslate(transform, 0, size.height)
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
break
case UIImageOrientation.Up, UIImageOrientation.UpMirrored:
break
}
switch imageOrientation {
case UIImageOrientation.UpMirrored, UIImageOrientation.DownMirrored:
CGAffineTransformTranslate(transform, size.width, 0)
CGAffineTransformScale(transform, -1, 1)
break
case UIImageOrientation.LeftMirrored, UIImageOrientation.RightMirrored:
CGAffineTransformTranslate(transform, size.height, 0)
CGAffineTransformScale(transform, -1, 1)
case UIImageOrientation.Up, UIImageOrientation.Down, UIImageOrientation.Left, UIImageOrientation.Right:
break
}
let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(size.width), Int(size.height), CGImageGetBitsPerComponent(CGImage), 0, CGImageGetColorSpace(CGImage), CGImageAlphaInfo.PremultipliedLast.rawValue)!
CGContextConcatCTM(ctx, transform)
switch imageOrientation {
case UIImageOrientation.Left, UIImageOrientation.LeftMirrored, UIImageOrientation.Right, UIImageOrientation.RightMirrored:
CGContextDrawImage(ctx, CGRectMake(0, 0, size.height, size.width), CGImage)
break
default:
CGContextDrawImage(ctx, CGRectMake(0, 0, size.width, size.height), CGImage)
break
}
let cgImage: CGImageRef = CGBitmapContextCreateImage(ctx)!
return UIImage(CGImage: cgImage)
}
}