iPhone AVFoundation camera orientation

前端 未结 12 585
走了就别回头了
走了就别回头了 2020-12-02 09:46

I\'ve been tearing my hair out trying to get the AVFoundation camera to capture a picture in the correct orientation (i.e. the device orientation) but I can\'t get it to wor

12条回答
  •  执笔经年
    2020-12-02 10:37

    I am writing this code in Swift in case may be needful for someone.

    Step-1: Generate Orientation notifications (in yourviewDidLoad)

        UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("deviceOrientationDidChange:"), name: UIDeviceOrientationDidChangeNotification, object: nil)
    

    Step-2: Take picture. Here we will interchange orientation of videoConnection. In AVFoundation there is a minor change in orientation especially for landscape orientation. So we will just interchange it. For example we will change from LandscapeRight to LandscapeLeft and viceversa

      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()
    
    
          }
        }
    
    
      }
    }
    
      }
    

    NOTE: Please notice the new orientation value for Landscape orientations. Its just the opposite. (This is the culprit ::UHHHH)

    Step-3: Fix orientation (UIImage extension)

    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)
    }
    
    
       }
    

提交回复
热议问题