UIImagePickerController 前置摄像头在预览视图上显示镜像

问题描述 投票:0回答:2

我知道很多人问过这个问题,但我没有找到解决此问题的正确答案,我的问题是:如何在预览视图上制作照片(用户点击拍摄按钮后,然后转到预览视图让用户预览)不是镜像,可以在 UIImagePickerController 中解决这个问题吗?我知道如何旋转照片,

UIImageOrientation
中的枚举中的某些内容,例如
UIImageOrientationUp 
,我知道这意味着什么。

尝试1:

我会在用户点击capture按钮后获取照片,然后再进入预览视图,并使用我有镜子的照片覆盖默认照片(使用

cameraOverlayView
),我可以检测到用户点击capture按钮使用
NSNotificationCenter
@"_UIImagePickerControllerUserDidCaptureItem",但我找不到办法获取照片。

尝试2:

我使用

cameraViewTransform
,但是当用户拍照(前置摄像头)时,当底部或顶部的Home按钮时,预览视图上的图像不是镜像,但是当左侧或右侧的
Home
按钮时,尽管预览视图上的图像不是镜像,但在用户点击capture之前,手机上的图像存在一些问题。使用
AVCaptureDeviceDidStartRunningNotification
通知。

- (void)cameraChanged:(NSNotification *)notification
{
  if(self.imagePickerController.cameraDevice == UIImagePickerControllerCameraDeviceFront)
  {
     self.imagePickerController.cameraViewTransform = CGAffineTransformIdentity;
     self.imagePickerController.cameraViewTransform = CGAffineTransformScale(self.imagePickerController.cameraViewTransform, -1, 1);
     if (self.imagePickerController.cameraOverlayView) {
        NSLog_DEBUG(@"self.imagePickerController.cameraOverlayView is not nil");
    } else {
        NSLog_DEBUG(@"self.imagePickerController.cameraOverlayView is nil");
    }
    self.imagePickerController.cameraOverlayView.transform = CGAffineTransformScale(self.imagePickerController.cameraViewTransform, -1, 1);
  } else {
    self.imagePickerController.cameraViewTransform = CGAffineTransformIdentity;
  }
}
ios objective-c uiimagepickercontroller
2个回答
2
投票

最后,我无法在

UIImagePickerController
中解决这个问题,但是我使用
AVFoundation
CoreMotion
解决了这个问题,你可以看到AVCam

//init the motionManager
- (void)initializeMotionManager{
  motionManager = [[CMMotionManager alloc] init];
  motionManager.accelerometerUpdateInterval = .1;
  motionManager.gyroUpdateInterval = .1;

  [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
                                    withHandler:^(CMAccelerometerData  *accelerometerData, NSError *error) {
                                        if (!error) {
                                            [self outputAccelertionData:accelerometerData.acceleration];
                                        }
                                        else{
                                            NSLog_DEBUG(@"%@", error);
                                        }
                                    }];
  }

//detect the device orientation
- (void)outputAccelertionData:(CMAcceleration)acceleration{

  if (acceleration.x >= 0.75) {
      _orientationNew = UIInterfaceOrientationLandscapeLeft;
  }
  else if (acceleration.x <= -0.75) {
      _orientationNew = UIInterfaceOrientationLandscapeRight;
  }
  else if (acceleration.y <= -0.75) {
      _orientationNew = UIInterfaceOrientationPortrait;
  }
  else if (acceleration.y >= 0.75) {
      _orientationNew = UIInterfaceOrientationPortraitUpsideDown;
  }
  else {
      // Consider same as last time
      return;
  }

  if (_orientationNew == _orientationLast)
      return;

  _orientationLast = _orientationNew;
}

0
投票

下午好。也许我回答晚了,但今天我解决了这个问题。 下面是解决UIImagePickerController预览镜像问题的代码

`

struct AddImageFromLibrary: UIViewControllerRepresentable {
    
    @Environment(\.presentationMode) private var presentationMode
    
    @Binding var sourceType: UIImagePickerController.SourceType
    @Binding var selectedImage: UIImage?

    
    func makeUIViewController(context: UIViewControllerRepresentableContext<AddImageFromLibrary>) -> UIImagePickerController {
        let imagePicker = CameraCaptureViewController()
        imagePicker.allowsEditing = true
        imagePicker.sourceType = sourceType
        imagePicker.delegate = context.coordinator
        imagePicker.modalPresentationStyle = .fullScreen
        return imagePicker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<AddImageFromLibrary>) {}
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        var parent: AddImageFromLibrary
        init(_ parent: AddImageFromLibrary) {
            self.parent = parent
        }
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[.editedImage] as? UIImage {
    
                let imageMirroriedNorm = UIImage(cgImage: image.cgImage!, scale: image.scale, orientation: .upMirrored) // mirroed photo
                parent.selectedImage = image
                if picker.sourceType == .camera && picker.cameraDevice == .front{
                    parent.selectedImage = imageMirroriedNorm
                    print("Mirror")
                }else{
                    parent.selectedImage = image
                    print("Original")
                }
            }
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

protocol CameraCaptureViewControllerDelegate {
    func cameraPositionDidChanged(newPosition: AVCaptureDevice.Position)
}

class CameraCaptureViewController: UIImagePickerController {

    var lastKnownPosition = AVCaptureDevice.Position.unspecified {
        didSet {
            cameraDelegate?.cameraPositionDidChanged(newPosition: lastKnownPosition)
        }
    }

    var cameraDelegate: CameraCaptureViewControllerDelegate?
    weak private var session: AVCaptureSession?
    private var context = 0

    deinit {
        session?.removeObserver(self, forKeyPath: "inputs")
        NotificationCenter.default.removeObserver(self)
    }
    
    override func viewDidLoad() {
        let notificationCenter = NotificationCenter.default

        notificationCenter.addObserver(forName: NSNotification.Name(rawValue: "_UIImagePickerControllerUserDidCaptureItem"), object: nil, queue: nil) { [weak self] (notification) in
            if self?.lastKnownPosition == .front {
                self?.changePhotoOrientation()
            }
        }

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

    func changePhotoOrientation() {
        var subviews: [UIView] = [view]

        while !subviews.isEmpty {
            let subview = subviews.removeFirst()
            subviews += subview.subviews
            if (subview.isKind(of: UIImageView.self)) {
                subview.transform = cameraViewTransform.scaledBy(x: -1, y: 1)
            }
        }
    }

    func handleCaptureSessionDidStartRunning(notification: Notification){
        guard let session = notification.object as? AVCaptureSession else { return }
        self.session = session
        if let input = session.inputs.first as? AVCaptureDeviceInput {
            lastKnownPosition = input.device.position
        }
        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 let inputs = change?[NSKeyValueChangeKey.newKey] as? [AnyObject], let captureDevice = (inputs.first as? AVCaptureDeviceInput)?.device {
            lastKnownPosition = captureDevice.position
        }
    }
}

`

© www.soinside.com 2019 - 2024. All rights reserved.