         DispatchQueue.global(qos: .default).async(execute: { () -> Void in
 
             let videoConnection = imageOutput.connection(withMediaType: AVMediaTypeVideo)
-
-            let orientation = self.currentDeviceOrientation ?? UIDevice.current.orientation
-            
-            switch (orientation) {
-            
-            case .portrait:
-            
-                videoConnection?.videoOrientation = .portrait
-            
-            case .portraitUpsideDown:
-            
-                videoConnection?.videoOrientation = .portraitUpsideDown
-            
-            case .landscapeRight:
-            
-                videoConnection?.videoOrientation = .landscapeLeft
-            
-            case .landscapeLeft:
-            
-                videoConnection?.videoOrientation = .landscapeRight
-            
-            default:
-            
-                videoConnection?.videoOrientation = .portrait
-            }
-
+            
             imageOutput.captureStillImageAsynchronously(from: videoConnection) { (buffer, error) -> Void in
                 
                 self.stopCamera()
                 
                 guard let data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer),
                     let image = UIImage(data: data),
-                    let delegate = self.delegate else {
+                    let cgImage = image.cgImage,
+                    let delegate = self.delegate,
+                    let videoLayer = self.videoLayer else {
                         
                         return
                 }
                 
-                // Image size
-                let iw: CGFloat
-                let ih: CGFloat
-                
-                switch (orientation) {
-                    
-                case .landscapeLeft, .landscapeRight:
-                    
-                    // Swap width and height if orientation is landscape
-                    iw = image.size.height
-                    ih = image.size.width
-                    
-                default:
-                    
-                    iw = image.size.width
-                    ih = image.size.height
-                    
-                }
-                
-                // Frame size
-                let sw = self.previewViewContainer.frame.width
-                
-                // The center coordinate along Y axis
-                let rcy = ih * 0.5
-                
-                guard let imageRef = image.cgImage?.cropping(to: CGRect(x: rcy-iw*0.5, y: 0 , width: iw, height: iw)) else {
+                let rect   = videoLayer.metadataOutputRectOfInterest(for: videoLayer.bounds)
+                let width  = CGFloat(cgImage.width)
+                let height = CGFloat(cgImage.height)
+                
+                let cropRect = CGRect(x: rect.origin.x * width,
+                                      y: rect.origin.y * height,
+                                      width: rect.size.width * width,
+                                      height: rect.size.height * height)
+                
+                guard let img = cgImage.cropping(to: cropRect) else {
                     
                     return
                 }
                 
+                let croppedUIImage = UIImage(cgImage: img, scale: 1.0, orientation: image.imageOrientation)
+                
                 DispatchQueue.main.async(execute: { () -> Void in
                     
-                    let image = fusumaCropImage ? UIImage(cgImage: imageRef, scale: sw/iw, orientation: image.imageOrientation) : image
-                    
-                    delegate.cameraShotFinished(image)
+                    delegate.cameraShotFinished(croppedUIImage)
                     
                     if fusumaSavesImage {
                         
-                        self.saveImageToCameraRoll(image: image)
+                        self.saveImageToCameraRoll(image: croppedUIImage)
                     }
                     
                     self.session       = nil
+                    self.videoLayer    = nil
                     self.device        = nil
                     self.imageOutput   = nil
                     self.motionManager = nil

                 
                        videoInput = try AVCaptureDeviceInput(device: device)
                        session.addInput(videoInput)
                        
                    }
                }

            }
            
            session?.commitConfiguration()

            
        } catch {
            

            
            session.addOutput(imageOutput)
            
            videoLayer = AVCaptureVideoPreviewLayer(session: session)
            videoLayer?.frame = self.previewViewContainer.bounds
            videoLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            
