67

を使用して、iPad2で前面カメラアプリを開発していUIImagePickerControllerます。

画像をキャプチャすると、左から右に反転して表示されます。

これを修正するにはどうすればよいですか?

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

9 に答える 9

77

これを使用して、ソース画像から画像を反転できます

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

編集:迅速なコードを追加

let flippedImage = UIImage(CGImage: picture.CGImage, scale: picture.scale, orientation:.LeftMirrored)
于 2012-02-13T04:38:17.283 に答える
19

私は同じ問題を抱えていました-そして、ユーザーが私のアプリの次のページに行く前にミラーリングされた画像を承認する必要があったので、上記の解決策は私に半分の答えしか得られませんでした-そこで私はそれをめくった後にキャプチャされた画像を使用します。

これを解決するには、正面カメラに切り替えるたびにカメラビューを反転する必要がありました。

- (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)が必要です。

-(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];
    }
于 2012-08-13T20:29:43.777 に答える
10

他の答えと同じように、私も同じ問題を抱えていました。Yonatan Betzerが述べたように、フロントカメラで写真を撮ったときにUIPickerControllerによって表示されるプレビュー画像はまだ反転(ミラーリング)されているため、最終画像を反転するだけで答えは半分になります。

Yonatan Betzerの回答はうまく機能しますが、カメラデバイスを変更するためのアクションをどこにどのように配置するかについては言及していません。

インターネットからのいくつかのコードに基づいて、私はこの望まれる振る舞いを得るためにポッドを作成しました:

https://github.com/lucasecf/LEMirroredImagePicker

UIImagePickerControllerインストール後、この2行のコードを:と一緒に呼び出す必要があります。

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

そして、それはそれだけです。詳細については、githubリンクのREADMEで確認できます。

于 2013-07-21T19:09:09.397 に答える
6

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;
    }
}
于 2013-12-16T10:01:19.823 に答える
6

この質問は本当に古いことは知っていますが、これはまだ一般的な問題のようです。オブジェクトCGAffineTransformcameraViewTransformプロパティにを設定するだけです。UIImagePickerController

let picker = UIImagePickerController()
picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, -1, 1)
于 2014-11-22T08:19:09.873 に答える
5

swift4の「バンドッグ」回答を更新

let picker = UIImagePickerController()
picker.cameraViewTransform = picker.cameraViewTransform.scaledBy(x: -1, y: 1)
于 2018-07-13T00:55:33.073 に答える
2

AVCaptureDeviceDidStartRunningNotificationカメラデバイスの変更を検出する手段として使用できなくなったようです。また、上のcameraDeviceプロパティUIImagePickerControllerはKVOでは機能しません。ただし、以下に示すように、カメラデバイスの変更を検出することは可能です(ただし、KVO準拠として明示的にマークされていないプロパティで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)
    }
}

Swift 4+バージョン:

import AVFoundation

var context = 0

override func viewDidLoad() {
    super.viewDidLoad()
    // Register for notifications
    let notificationCenter = NSNotificationCenter.defaultCenter()
    notificationCenter.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureSessionDidStartRunningNotification"), object: nil, queue: nil) { [weak self] notification in
        self?.handleCaptureSessionDidStartRunning(notification: notification)
    }
    notificationCenter.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureSessionDidStopRunningNotification"), object: nil, queue: nil) { [weak self] 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)
    }
}
于 2016-08-15T02:10:18.110 に答える
2

数時間かかりましたが、そこに着いたと思います。これは、正しい画像を取得する方法(ImagePickerプレビューと出力の両方)のSwift5.2実用的なソリューションです。


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

}

于 2020-05-04T12:20:39.530 に答える
0

この投稿の最初の質問に答えるSwiftの完全な動作例(iOS8.2を使用してiPhone5cでテスト済み):

        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
于 2015-03-16T03:23:59.187 に答える