首页 > 解决方案 > 从相机拍摄的iphone图像自动旋转Swift

问题描述

以编程方式,我在我的应用程序中从我的相机捕获了图像。它已经很好地获取了,但是当我转移到另一个时,查看并关闭那个视图我想旋转到横向的图像。我从相机捕捉图像。当我从照片库中获取图像时,没有发现任何问题。

下图是我的原图。 截屏

我想旋转图像。 截屏

下面的代码:

var captureSesssion : AVCaptureSession!
var cameraOutput : AVCapturePhotoOutput!
var previewLayer : AVCaptureVideoPreviewLayer!
var device:AVCaptureDevice!
var currentViewControl = UIViewController()
var tempImageHolder = UIImage()

func beginCamera(_ targetView: UIView, _ currentVC: UIViewController) 
{ 
    currentViewControl = currentVC
    // Do any additional setup after loading the view, typically from a nib.
    captureSesssion = AVCaptureSession()
    captureSesssion.sessionPreset = AVCaptureSession.Preset.photo
    cameraOutput = AVCapturePhotoOutput()

    if #available(iOS 11.1, *) {
        let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera], mediaType: AVMediaType.video, position: .back).devices
        device = availableDevices.first
    } else {
        // Fallback on earlier versions
        device = AVCaptureDevice.default(for: .video)!
    }

    if let input = try? AVCaptureDeviceInput(device: device!) {
        if (captureSesssion.canAddInput(input)) {
            captureSesssion.addInput(input)
            if (captureSesssion.canAddOutput(cameraOutput)) {
                captureSesssion.addOutput(cameraOutput)
                let connection = cameraOutput.connection(with: AVFoundation.AVMediaType.video)
                connection?.videoOrientation = .portrait
                previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
                self.previewLayer.frame = targetView.frame
                self.previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                //setOutputOrientation()
                targetView.layer.addSublayer(previewLayer)
                captureSesssion.startRunning()
            }
        } else {
            print("issue here : captureSesssion.canAddInput")
        }
    } else {
        print("some problem here")
    }
    previewLayer?.frame.size = targetView.frame.size
}

   func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
    if let error = error {
        // we got back an error!
        let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        currentViewControl.present(alert, animated: true)
    } else {
    }}


 func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    let imageData = photo.fileDataRepresentation()
    let imageSize: Int = imageData!.count
    print(imageSize)
    tempImageHolder = UIImage(data: (imageData! as NSData) as Data)!
    //When use this below line works fine when take images from left landscape, but when take images from right landscape image not show properly screen shot below:
    tempImageHolder = UIImage(cgImage: tempImageHolder.cgImage!, scale: tempImageHolder.scale, orientation: .up)
    }
}

从左侧横向拍摄图像时:

输入: 屏幕截图

输出: 屏幕截图

从右侧风景拍摄图像时

输入: 屏幕截图

输出: 屏幕截图

UIImage(cgImage: tempImageHolder.cgImage!, scale: tempImageHolder.scale, orientation: .up)

当从左侧横向拍摄图像时使用上面的这条线可以正常工作,但是从右侧横向图像拍摄图像时无法正确显示屏幕截图

有人可以向我解释如何旋转图像。任何帮助将不胜感激。

提前致谢。

标签: iosswiftxcodecamera

解决方案


这是一个非常烦人的问题,我真的不敢相信 AVFoundation 没有让我们更轻松的事情。但在我的应用程序中,我通过保持当前设备方向来做到这一点。当照片输出带有图像时,使用方向旋转图像以确保所有图像都向上。

class MyViewController: UIViewController {

    var currentOrientation: UIDeviceOrientation = .portrait

    override func viewDidLoad() {
        NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)
    }

    @objc func orientationChanged() {
        currentOrientation = UIDevice.current.orientation
    }

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        guard let img = photo.cgImageRepresentation()?.takeUnretainedValue() else { return }
        let temp = CIImage(cgImage: img)
        var ciImage = temp;
        switch currentOrientation {
            case .portrait:
                ciImage = temp.oriented(forExifOrientation: 6)
            case .landscapeRight:
                ciImage = temp.oriented(forExifOrientation: 3)
            case .landscapeLeft:
                ciImage = temp.oriented(forExifOrientation: 1)
            default:
                break
        }

        guard let cgImage = CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent) else { return }
        let fixedImage = UIImage(cgImage: cgImage)
    }


}

最后,根据您的需要使用fixedImage。请注意,我订阅了通知中心以了解方向的变化。


推荐阅读