Je développe l'application pour caméra frontale dans iPad2 à l'aide de la variable UIImagePickerController
.
Lorsque je capture l'image, elle est retournée de gauche à droite.
Comment puis-je corriger cela?
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];
}
Vous pouvez retourner l’image de l’image source en utilisant cette
UIImage *flippedImage = [UIImage imageWithCGImage:picture.CGImage scale:picture.scale orientation:UIImageOrientationLeftMirrored];
Édition: Ajout du code Swift
let flippedImage = UIImage(CGImage: picture.CGImage, scale: picture.scale, orientation:.LeftMirrored)
J'ai eu le même problème - et la solution ci-dessus ne m'a donné que la moitié de la réponse, car l'utilisateur devait approuver l'image en miroir avant de passer à la page suivante de mon application - où j'utilise l'image capturée après l'avoir retournée.
Pour résoudre ce problème, je devais inverser la vue de la caméra chaque fois que je passais devant la caméra:
- (IBAction)flipCamera:(id)sender {
if(cameraUI.cameraDevice == UIImagePickerControllerCameraDeviceFront)
{
cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceRear;
}
else {
cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceFront;
}
cameraUI.cameraViewTransform = CGAffineTransformScale(cameraUI.cameraViewTransform, -1, 1);
}
Juste pour développer cette excellente réponse, du code complet typique, Dec2013, iOS7/Xcode5. Fait tout. Vous avez juste besoin d'une icône (cameraToggle.PNG dans l'exemple).
-(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];
}
Comme l’autre réponse, j’ai eu le même problème. Comme l'a mentionné Yonatan Betzer, il suffit d'inverser l'image finale pour obtenir la moitié de la réponse, car l'image d'aperçu affichée par le contrôleur UIPicker lorsque vous prenez une photo avec l'appareil photo avant est toujours inversée (en miroir).
La réponse de Yonatan Betzer fonctionne très bien, mais il n'a pas précisé comment ni où mettre l'action pour changer l'appareil photo.
Basé sur des codes d’internet, j’ai créé un pod pour obtenir ce comportement recherché:
https://github.com/lucasecf/LEMirroredImagePicker
Une fois installé, il vous suffit d’appeler ces deux lignes de code avec votre UIImagePickerController
:
self.mirrorFrontPicker = [[LEMirroredImagePicker alloc] initWithImagePicker:pickerController];
[self.mirrorFrontPicker mirrorFrontCamera];
Et c'est tout, simplement comme ça. Vous pouvez rechercher plus d'informations dans le README du lien github.
Je sais que cette question est vraiment ancienne, mais il semble que cela reste un problème commun. Il suffit de définir CGAffineTransform
sur la propriété cameraViewTransform
sur un objet UIImagePickerController
.
let picker = UIImagePickerController()
picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, -1, 1)
Juste pour ajouter comment je viens de réaliser ceci sans sous-classer UIImagePickerController et sans ajouter de boutons supplémentaires à la vue caméra.
Écoutez simplement cette notification qui est déclenchée plusieurs fois à chaque changement de caméra:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cameraChanged:)
name:@"AVCaptureDeviceDidStartRunningNotification"
object:nil];
Ensuite, utilisez cette méthode pour retourner la vue de la caméra:
- (void)cameraChanged:(NSNotification *)notification
{
if(imagePicker.cameraDevice == UIImagePickerControllerCameraDeviceFront)
{
imagePicker.cameraViewTransform = CGAffineTransformIdentity;
imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, -1, 1);
} else {
imagePicker.cameraViewTransform = CGAffineTransformIdentity;
}
}
Mise à jour de la réponse "bandog" pour Swift 4
let picker = UIImagePickerController()
picker.cameraViewTransform = picker.cameraViewTransform.scaledBy(x: -1, y: 1)
Il semblerait que AVCaptureDeviceDidStartRunningNotification
ne soit plus disponible pour détecter les modifications apportées au périphérique de la caméra. De plus, la propriété cameraDevice
sur UIImagePickerController
ne fonctionne pas avec KVO. Toutefois, il est toujours possible de détecter les modifications apportées aux appareils photo, comme indiqué ci-dessous (bien que la prise en charge à long terme de cette solution ne soit pas garantie, car nous utilisons KVO sur une propriété non explicitement marquée comme compatible KVO).
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)
}
}
Exemple de travail complet dans Swift , qui répond à la question initiale de ce message (testé sur un iPhone 5c utilisant 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