web-dev-qa-db-de.com

Frontkamera in UIImagePickerController

Ich entwickle die Kamera-Frontkamera-App in iPad2 mithilfe der UIImagePickerController.

Wenn ich das Bild aufnehme, wird es als von links nach rechts gedreht angezeigt.

Wie korrigiere ich das?

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) 
    {
        UIImagePickerController *imgPkr = [[UIImagePickerController alloc] init];
        imgPkr.delegate = self;
        imgPkr.sourceType = UIImagePickerControllerSourceTypeCamera;
        imgPkr.cameraDevice=UIImagePickerControllerCameraDeviceFront;


        UIImageView *anImageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"select%d.png",val]]];
        anImageView.frame = CGRectMake(0, 0, anImageView.image.size.width, anImageView.image.size.height);
        imgPkr.cameraOverlayView = anImageView;
        [theApp.TabViewControllerObject presentModalViewController:imgPkr animated:YES];
        [imgPkr release];
    }
64
dineshprasanna

Mit diesem können Sie das Bild vom Quellbild umkehren

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

Bearbeiten: Swift-Code hinzugefügt

let flippedImage = UIImage(CGImage: picture.CGImage, scale: picture.scale, orientation:.LeftMirrored)
75

Ich hatte das gleiche Problem - und die Lösung oben brachte mir nur die Hälfte der Antwort, da der Benutzer das gespiegelte Bild genehmigen musste, bevor ich zur nächsten Seite meiner App komme - wo ich das aufgenommene Bild nach dem Spiegeln verwende.

Um dieses Problem zu lösen, musste ich die Kameraansicht umdrehen, wenn ich zur Frontkamera wechsle:

- (IBAction)flipCamera:(id)sender {
if(cameraUI.cameraDevice == UIImagePickerControllerCameraDeviceFront)
{
    cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceRear;
}
else {
    cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceFront;
}
cameraUI.cameraViewTransform = CGAffineTransformScale(cameraUI.cameraViewTransform, -1,     1);     
}

Nur um diese großartige Antwort zu erweitern, einige typische vollständige Codes, Dec2013, iOS7/Xcode5. Macht alles. Sie benötigen lediglich ein Symbol (cameraToggle.PNG im Beispiel).

-(void)showTheDeviceCamera
    {
    if ( ! [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] )
        return;

    // self.cameraController is a UIImagePickerController
    self.cameraController = [[UIImagePickerController alloc] init];
    self.cameraController.delegate = (id)self;
    self.cameraController.mediaTypes = @[(NSString *)kUTTypeImage];
    self.cameraController.allowsEditing = YES;
    self.cameraController.sourceType = UIImagePickerControllerSourceTypeCamera;
    [self presentViewController:self.cameraController animated:YES completion:NULL];


        // Add front-rear toggle button MANUALLY, IF NECESSARY
        // (You seem to usually get it for free, on iPhone, but
        // need to add manually on an iPad.)

        UIView *buttonView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cameraToggle"]];
        [buttonView sizeToFit];

        buttonView.userInteractionEnabled = YES;
        [self.cameraController.view addSubview:buttonView];

        UITapGestureRecognizer *tap =
            [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_frontRearButtonClicked) ];
        tap.numberOfTapsRequired = 1;
        [buttonView addGestureRecognizer:tap];

        // we'll add it at the top right .. could be anywhere you want
        buttonView.center = CGPointMake(
                self.cameraController.view.frame.size.width-buttonView.frame.size.width,
                3.0 * buttonView.frame.size.height
                );

    }

-(void)_frontRearButtonClicked
    {
    [UIView transitionWithView:self.cameraController.view
        duration:1.0
        options:UIViewAnimationOptionAllowAnimatedContent | UIViewAnimationOptionTransitionFlipFromLeft
        animations:^{
            if ( self.cameraController.cameraDevice == UIImagePickerControllerCameraDeviceRear )
                self.cameraController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
            else
                self.cameraController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
        } completion:NULL];
    }
19
Yonatan Betzer

Bei den anderen Antworten hatte ich das gleiche Problem. Wie schon Yonatan Betzer erwähnt hat, ist das fertige Bild nur die Hälfte der Antwort, da das Vorschaubild, das vom UIPickerController angezeigt wird, wenn Sie ein Bild mit der Frontkamera aufnehmen, immer noch invertiert (gespiegelt) ist.

Die Beantwortung von Yonatan Betzer funktioniert hervorragend, aber er hat nicht erwähnt, wie oder wo die Aktion zum Wechseln des Kamerageräts zu setzen ist.

Basierend auf einigen Codes aus dem Internet habe ich einen Pod erstellt, um dieses gewünschte Verhalten zu erhalten: 

https://github.com/lucasecf/LEMirroredImagePicker

Nach der Installation müssen Sie diese zwei Codezeilen zusammen mit Ihrer UIImagePickerController aufrufen:

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

Und das ist es, einfach so. Weitere Informationen finden Sie im README des Github-Links.

9
Lucas Eduardo

Ich weiß, dass diese Frage wirklich alt ist, aber es scheint immer noch ein häufiges Problem zu sein. Legen Sie einfach eine CGAffineTransform in der cameraViewTransform-Eigenschaft eines UIImagePickerController-Objekts fest. 

let picker = UIImagePickerController()
picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, -1, 1)
6
barndog

Ich möchte nur hinzufügen, wie ich dies gerade erreicht habe, ohne UIImagePickerController zu subklassifizieren und der Kameraansicht zusätzliche Schaltflächen hinzuzufügen.

Hören Sie einfach auf diese Benachrichtigung, die bei jedem Wechsel der Kamera mehrmals ausgelöst wird:

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

Verwenden Sie dann diese Methode, um die Kameraansicht umzudrehen:

- (void)cameraChanged:(NSNotification *)notification
{
    if(imagePicker.cameraDevice == UIImagePickerControllerCameraDeviceFront)
    {
        imagePicker.cameraViewTransform = CGAffineTransformIdentity;
        imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, -1,     1);
    } else {
        imagePicker.cameraViewTransform = CGAffineTransformIdentity;
    }
}
6
Darren

Aktualisierte Antwort "Bandog" für Swift 4

let picker = UIImagePickerController()
picker.cameraViewTransform = picker.cameraViewTransform.scaledBy(x: -1, y: 1)
1
user3054579

Es sieht so aus, als wäre AVCaptureDeviceDidStartRunningNotification nicht mehr verfügbar, um Kamerageräteänderungen zu erkennen. Die cameraDevice-Eigenschaft in UIImagePickerController funktioniert auch nicht mit KVO. Es ist jedoch immer noch möglich, Änderungen an Kameravorrichtungen zu erkennen (siehe unten) (Langfristiger Support für diese Lösung kann jedoch nicht garantiert werden, da wir KVO für eine Eigenschaft verwenden, die nicht ausdrücklich als KVO-kompatibel gekennzeichnet ist).

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

Vollständiges Funktionsbeispiel in Swift , das die erste Frage dieses Beitrags beantwortet (getestet auf einem iPhone 5c mit iOS 8.2):

        import UIKit

        class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIActionSheetDelegate {

         @IBOutlet var myUIImageView: UIImageView!

         var myUIImagePickerController: UIImagePickerController!

         override func viewDidLoad() {
             super.viewDidLoad()
         }

         override func viewWillAppear(animated: Bool) {
             println("viewWillAppear(animated: Bool) method called.")
             super.viewWillAppear(animated)
             NSNotificationCenter.defaultCenter().removeObserver(self)
         }

         override func viewWillDisappear(animated: Bool) {
             println("viewWillDisappear(animated: Bool) method called.")
             super.viewWillDisappear(animated)
             NSNotificationCenter.defaultCenter().addObserver(self, selector: "cameraChanged:", name: "AVCaptureDeviceDidStartRunningNotification", object: nil)
         }

         /* UIImagePickerControllerDelegate Section */
         func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
              if(self.myUIImagePickerController.sourceType == UIImagePickerControllerSourceType.Camera) {
                 self.myUIImageView.image = info[UIImagePickerControllerEditedImage] as? UIImage
              } else {
                 self.myUIImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
              }
              self.dismissViewControllerAnimated(true, completion: nil)
         }

        func imagePickerControllerDidCancel(picker: UIImagePickerController) {
            self.dismissViewControllerAnimated(true, completion: nil)
        }

        /*
        You can choose to use one of the UIResponder methods:
        touchesBegan, touchesMoved, touchesEnded etc, in order to detect the touch
        on the UIImageView.
        */
        override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
            let touch: UITouch? = touches.anyObject() as? UITouch
            if (touch?.view == myUIImageView) {
                println("myUIImageView has been tapped by the user.")
                self.takingAPictureUsingTheCamera()
            }
        }

        func takingAPictureUsingTheCamera() {
            self.myUIImagePickerController = UIImagePickerController()
            self.myUIImagePickerController.delegate = self // Set the delegate
            self.myUIImagePickerController.sourceType = UIImagePickerControllerSourceType.Camera
            self.myUIImagePickerController.cameraDevice = UIImagePickerControllerCameraDevice.Front
    //        self.myUIImagePickerController.editing = true
            self.myUIImagePickerController.allowsEditing = true
            self.presentViewController(self.myUIImagePickerController, animated: true, completion: nil)
        }

        func cameraChanged(notification: NSNotification) {
             println("cameraChanged(notification: NSNotification) method called.")
             self.myUIImagePickerController.cameraViewTransform = CGAffineTransformIdentity
             if(self.myUIImagePickerController.cameraDevice == UIImagePickerControllerCameraDevice.Front){
                 self.myUIImagePickerController.cameraViewTransform = CGAffineTransformScale(self.myUIImagePickerController.cameraViewTransform, -1, 1)
             }
        }
       }// End class
0
King-Wizard