IT TIP

UIImagePickerController의 전면 카메라

itqueen 2020. 11. 20. 17:32
반응형

UIImagePickerController의 전면 카메라


.NET Framework를 사용하여 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];
    }

소스 이미지에서 이미지를 뒤집을 수 있습니다.

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

편집 : 신속한 코드 추가

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

이 훌륭한 답변을 확장하기 위해 일반적인 완전한 코드 인 Dec2013, 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];
    }

다른 답변과 마찬가지로 동일한 문제가 발생했습니다. Yonatan Betzer가 언급했듯이, 전면 카메라로 사진을 찍을 때 UIPickerController에 의해 표시되는 미리보기 이미지는 여전히 반전 (미러링)되어 있기 때문에 최종 이미지를 뒤집는 것은 답의 절반에 불과합니다.

Yonatan Betzer의 anwser는 훌륭하게 작동하지만 카메라 장치를 변경하기 위해 작업을 수행하는 방법과 위치에 대해서는 언급하지 않았습니다.

인터넷의 일부 코드를 기반으로이 원하는 동작을 얻기 위해 포드를 만들었습니다.

https://github.com/lucasecf/LEMirroredImagePicker

설치 후 다음 두 줄의 코드를 다음과 같이 호출하면됩니다 UIImagePickerController.

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

그리고 그게 다입니다. github 링크의 README에서 자세한 정보를 확인할 수 있습니다.


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

나는이 질문이 정말 오래되었다는 것을 알고 있지만 이것이 여전히 일반적인 문제인 것 같습니다. 객체 CGAffineTransformcameraViewTransform속성에 a를 설정하십시오 UIImagePickerController.

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

Swift 4에 대한 "bandog"답변 업데이트

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

이 게시물의 초기 질문에 대한 답변 인 Swift의 전체 작업 예제 (iOS 8.2를 사용하는 iPhone 5c에서 테스트 됨) :

        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

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

참고URL : https://stackoverflow.com/questions/9255633/front-facing-camera-in-uiimagepickercontroller

반응형