Front facing camera in UIImagePickerController

后端 未结 9 1228
暗喜
暗喜 2020-12-02 06:42

I am developing the front facing camera app in iPad2 by using the UIImagePickerController.

When I capture the image it\'s shows as flipped from left to

相关标签:
9条回答
  • 2020-12-02 07:20

    I know this question is really old but it seems like this is a still a common problem. Just set a CGAffineTransform on the cameraViewTransform property on a UIImagePickerController object.

    let picker = UIImagePickerController()
    picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, -1, 1)
    
    0 讨论(0)
  • 2020-12-02 07:22

    You can flip the image from the source image use this

    UIImage *flippedImage = [UIImage imageWithCGImage:picture.CGImage scale:picture.scale orientation:UIImageOrientationLeftMirrored];
    

    Edit: Added swift code

    let flippedImage = UIImage(CGImage: picture.CGImage, scale: picture.scale, orientation:.LeftMirrored)
    
    0 讨论(0)
  • 2020-12-02 07:22

    It took me few hours, but I think I got there. Here is a working solution for Swift 5.2 of how to get correct image (both in ImagePicker preview and in output).

    
         //Registering to get notification when users takes a picture
    
        override func viewDidLoad() {
            NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "_UIImagePickerControllerUserDidCaptureItem"), object: nil, queue: nil) { (notification) in
                self.changePhotoOrientation()
        }
    
        //Changing image orientation for ImagePicker preview
    
        func changePhotoOrientation() {
            var subviews: [UIView] = [imagePicker.view]
            while (!subviews.isEmpty) {
                let subview = subviews.removeFirst()
                subviews += subview.subviews
                if (subview.isKind(of: UIImageView.self)) {
                    subview.transform = self.imagePicker.cameraViewTransform.scaledBy(x: -1, y: 1)
                }
            }
        }
    
        //Changing image orientation for the output image
    
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let userPickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                image = UIImage(cgImage: userPickedImage.cgImage!, scale: userPickedImage.scale, orientation: .leftMirrored)
            }
        }
    
    }
    
    
    0 讨论(0)
  • 2020-12-02 07:27

    As the other answers, I had the same problem. As Yonatan Betzer mentioned, just flip the final image is only half the answer, because the preview image, displayed by the UIPickerController when you take a picture with the front camera, it's still inverted (mirrored).

    Yonatan Betzer's anwser works great, but he did not mentioned how or where to put the action to change the camera device.

    Based in some codes from internet, I created a Pod to get this wanted behavior:

    https://github.com/lucasecf/LEMirroredImagePicker

    After installed, you just have to call this two lines of code together with your UIImagePickerController:

    self.mirrorFrontPicker = [[LEMirroredImagePicker alloc] initWithImagePicker:pickerController];
    [self.mirrorFrontPicker mirrorFrontCamera];
    

    And thats it, simply as that. You can check for more informations in the README of the github link.

    0 讨论(0)
  • 2020-12-02 07:33

    Just to add how I have just achieved this without subclassing UIImagePickerController and without adding extra buttons to the camera view.

    Simply listen for this notification which is fired several times whenever the camera is changed:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(cameraChanged:)
                                                     name:@"AVCaptureDeviceDidStartRunningNotification"
                                                   object:nil];
    

    Then use this method to flip the camera view:

    - (void)cameraChanged:(NSNotification *)notification
    {
        if(imagePicker.cameraDevice == UIImagePickerControllerCameraDeviceFront)
        {
            imagePicker.cameraViewTransform = CGAffineTransformIdentity;
            imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, -1,     1);
        } else {
            imagePicker.cameraViewTransform = CGAffineTransformIdentity;
        }
    }
    
    0 讨论(0)
  • 2020-12-02 07:34

    It looks like AVCaptureDeviceDidStartRunningNotification is no longer available as a means of detecting camera device changes. Also, the cameraDevice property on UIImagePickerController doesn't work with KVO. However, it's still possible to detect camera device changes, as shown below (though long-term support for this solution isn't guaranteed as we're using KVO on a property that isn't explicitly marked as KVO-compliant).

    import AVFoundation
    
    var context = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Register for notifications
        let notificationCenter = NSNotificationCenter.defaultCenter()
        notificationCenter.addObserver(self, selector: #selector(handleCaptureSessionDidStartRunning(_:)), name: AVCaptureSessionDidStartRunningNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(handleCaptureSessionDidStopRunning(_:)), name: AVCaptureSessionDidStopRunningNotification, object: nil)
    }
    
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    func handleCaptureSessionDidStartRunning(notification: NSNotification) {
        guard let session = notification.object as? AVCaptureSession else { return }
        session.addObserver(self, forKeyPath: "inputs", options: [ .Old, .New ], context: &context)
    }
    
    func handleCaptureSessionDidStopRunning(notification: NSNotification) {
        guard let session = notification.object as? AVCaptureSession else { return }
        session.removeObserver(self, forKeyPath: "inputs")
    }
    
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if context == &self.context {
            if let inputs = change?[NSKeyValueChangeNewKey] as? [AnyObject], captureDevice = (inputs.first as? AVCaptureDeviceInput)?.device {
                switch captureDevice.position {
                case .Back: print("Switched to back camera")
                case .Front: print("Switched to front camera")
                case .Unspecified: break
                }
            }
        } else {
            super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
        }
    }
    

    Swift 4+ version:

    import AVFoundation
    
    var context = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Register for notifications
        NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureSessionDidStartRunningNotification"), object: nil, queue: nil) { (notification) in
                self.handleCaptureSessionDidStartRunning(notification: notification)}
            
        NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureSessionDidStopRunningNotification"), object: nil, queue: nil) { (notification) in
                self.handleCaptureSessionDidStopRunning(notification: notification)}
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    func handleCaptureSessionDidStartRunning(notification: Notification){
        guard let session = notification.object as? AVCaptureSession else { return }
        session.addObserver(self, forKeyPath: "inputs", options: [ .old, .new ], context: &context)
    }
    
    func handleCaptureSessionDidStopRunning(notification: Notification){
        guard let session = notification.object as? AVCaptureSession else { return }
        session.removeObserver(self, forKeyPath: "inputs")
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if context == &self.context {
            if let inputs = change?[NSKeyValueChangeKey.newKey] as? [AnyObject], let captureDevice = (inputs.first as? AVCaptureDeviceInput)?.device {
                switch captureDevice.position {
                case .back: print("Switched to back camera")
                case .front: print("Switched to front camera")
                case .unspecified: break
                }
            }
        } else {
            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        }
    }
    
    0 讨论(0)
提交回复
热议问题