Ios UIImagePickerController中的前置摄像头

Ios UIImagePickerController中的前置摄像头,ios,objective-c,iphone,swift,uiimagepickercontroller,Ios,Objective C,Iphone,Swift,Uiimagepickercontroller,我正在使用UIImagePickerController在iPad2中开发前置摄像头应用程序 当我拍摄图像时,它显示为从左向右翻转 我如何纠正这个问题 if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { UIImagePickerController *imgPkr = [[UIImagePickerController alloc]

我正在使用
UIImagePickerController
在iPad2中开发前置摄像头应用程序

当我拍摄图像时,它显示为从左向右翻转

我如何纠正这个问题

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];
    }

您可以使用此选项从源图像翻转图像

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

编辑:添加了swift代码

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

我也遇到了同样的问题——上面的解决方案只给了我一半的答案,因为用户必须在进入我的应用程序的下一页之前批准镜像图像——在翻页后,我使用捕获的图像

为了解决这个问题,每当切换到前向摄像头时,我必须翻转摄像头视图:

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

下面是一些典型的完整代码,2013年12月,iOS7/Xcode5。什么都做。您只需要一个图标(示例中为cameraToggle.PNG)


和其他答案一样,我也有同样的问题。正如Yonatan Betzer所提到的,只需翻转最终图像仅是答案的一半,因为当您使用前摄像头拍照时,UIPickerController显示的预览图像仍然是反转(镜像)的

Yonatan Betzer的anwser工作得很好,但他没有提到如何或在何处采取行动来改变相机设备

根据互联网上的一些代码,我创建了一个Pod来获得这种想要的行为:

安装后,只需将这两行代码与
UIImagePickerController一起调用即可:

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

就这么简单。您可以在github链接的自述中查看更多信息。

只需添加我刚刚实现这一点的方法,而无需将UIImagePickerController子类化,也无需向相机视图添加额外按钮

只需收听此通知,每当更换相机时,此通知会多次触发:

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(cameraChanged:)
                                                 name:@"AVCaptureDeviceDidStartRunningNotification"
                                               object:nil];
然后使用此方法翻转摄影机视图:

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

我知道这个问题真的很老了,但似乎这仍然是一个普遍的问题。只需在
UIImagePickerController
对象的
cameraViewTransform
属性上设置一个
CGAffineTransform

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

Swift中的完整工作示例,回答了本文的初始问题(使用iOS 8.2在iPhone 5c上测试):


看起来,
AVCaptureDeviceIDStartRunningNotification
不再可用作检测摄像头设备更改的手段。另外,
UIImagePickerController
上的
cameraDevice
属性不适用于KVO。但是,仍然可以检测到摄像头设备的更改,如下所示(尽管无法保证对此解决方案的长期支持,因为我们在未明确标记为符合KVO的属性上使用KVO)

更新swift 4的“bandog”答案

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

我花了几个小时,但我想我到了那里。以下是如何获得正确图像的Swift 5.2的工作解决方案(在ImagePicker预览和输出中)


//注册以在用户拍照时获取通知
重写func viewDidLoad(){
NotificationCenter.default.addObserver(forName:NSNotification.Name(rawValue:“\u UIImagePickerController UserDidCaptureItem”),对象:nil,队列:nil){(通知)在
self.changePhotoOrientation()
}
//更改ImagePicker预览的图像方向
func changePhotoOrientation(){
变量子视图:[UIView]=[imagePicker.view]
而(!subviews.isEmpty){
让子视图=子视图。removeFirst()
子视图+=子视图。子视图
if(subview.isKind(of:UIImageView.self)){
subview.transform=self.imagePicker.cameraViewTransform.scaledBy(x:-1,y:1)
}
}
}
//更改输出图像的图像方向
func imagePickerController(picker:UIImagePickerController,didFinishPickingMediaWithInfo:[UIImagePickerController.InfoKey:Any]){
如果让userPickedImage=info[UIImagePickerController.InfoKey.originalImage]作为?UIImage{
image=UIImage(cgImage:userPickedImage.cgImage!,比例:userPickedImage.scale,方向:.leftMirrored)
}
}
}

为什么我的问题被否决了!请注意,在iPhone的大多数版本中,您似乎会自动获得闪光灯和前后按钮。(可能稍微取决于iOS的子版本)只有在iPad上才需要手动添加。我只是浪费时间仔细地开发一个按钮,因为我在iPadMini而不是iPhone上测试:)我不知道为什么它被否决了。我对你的问题给出了一个+1的答案。这是最有用的答案。你是如何设置翻转相机的目标动作的?您的故事板中是否有摄像头用户界面?如果您的用户不打算用前摄像头旋转手机进行横向拍摄,则此视图转换非常有效。:)我在LEImagePickerController类中使用你的类时遇到了下一个错误。m:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“源类型必须是UIImagePickerController源类型Camera”知道为什么吗?嗨@FernandoSantiago,你在模拟器中执行这些类,对吗?该项目假设在使用的设备中可以使用摄像头,不幸的是模拟器无法模拟摄像头,这就是它崩溃的原因。今天,我已经提交了一个解决方案来处理这个案例,如果没有可用的摄像头,则显示照片库,但您只能在设备中看到项目的全部功能,使用真实的摄像头,而不能在模拟器中看到。@LucasEduardo amigo这不起作用。。。“预览”图像(按下“使用”按钮时镜像不正确)@B-Man我刚刚用iphone6/iOS9/Xcode 7测试过,lib应该如何工作。试着从github下载zip并在您的设备中运行示例项目。如果您仍然有任何问题,请创建一个
        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
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)
    }
}
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)
    }
}
let picker = UIImagePickerController()
picker.cameraViewTransform = picker.cameraViewTransform.scaledBy(x: -1, y: 1)