【问题标题】:Camera only takes pictures in portrait mode swift相机仅在人像模式下快速拍照
【发布时间】:2016-08-02 12:33:37
【问题描述】:

如何将相机设置为横向模式?每次我拍照时,图像都会保存为肖像图像。当设备处于横向模式时,照片看起来不错,但如果我在相机胶卷中看到它,它仍然是纵向模式。 这是我的拍照功能:

// take a photo
@IBAction func takePhoto(sender: AnyObject) {
self.fullScreenView.hidden = false
self.recordButton.enabled = false
self.takephoto.enabled = false
self.recordButton.hidden = true
self.takephoto.hidden = true

session.startRunning()

// customize the quality level or bitrate of the output photo
session.sessionPreset = AVCaptureSessionPresetPhoto

// add the AVCaptureVideoPreviewLayer to the view and set the view in fullscreen
fullScreenView.frame = view.bounds
videoPreviewLayer.frame = fullScreenView.bounds
fullScreenView.layer.addSublayer(videoPreviewLayer)

// add action to fullScreenView
gestureFullScreenView = UITapGestureRecognizer(target: self, action: #selector(ViewController.takePhoto(_:)))
self.fullScreenView.addGestureRecognizer(gestureFullScreenView)

// add action to myView
gestureView = UITapGestureRecognizer(target: self, action: #selector(ViewController.setFrontpage(_:)))
self.view.addGestureRecognizer(gestureView)

if (preview == true) {
    if let videoConnection = stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo) {
        // code for photo capture goes here...

        stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
            // process the image data (sampleBuffer) here to get an image file we can put in our view

            if (sampleBuffer != nil) {
                let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                let image = UIImage(data: imageData, scale: 1.0)

                self.fullScreenView.hidden = true
                self.fullScreenView.gestureRecognizers?.forEach(self.fullScreenView.removeGestureRecognizer)
                self.session.stopRunning()

                // save image to the library
                UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)

                self.imageViewBackground = UIImageView(frame: self.view.bounds)
                self.imageViewBackground.image = image
                self.imageViewBackground.tag = self.key

                self.view.addSubview(self.imageViewBackground)
            }
        })
    }
}
else {
    preview = true
}
}

我的预览看起来像这样,没关系:

http://img5.fotos-hochladen.net/uploads/bildschirmfotom4s7diaehy.png

但最终看起来是这样的:

http://img5.fotos-hochladen.net/uploads/bildschirmfoto3c2rlwtevf.png

提前致谢!

【问题讨论】:

    标签: ios swift camera landscape portrait


    【解决方案1】:

    因为无论您的设备是纵向还是横向,您的 videoConnection 的方向 始终是纵向的。所以你应该在拍摄静态照片之前将 videoConnection 的方向调整到正确的方向

    添加如下方法获取当前deviceOrientation的videoOrientation

    func videoOrientation(for deviceOrientation: UIDeviceOrientation) -> AVCaptureVideoOrientation {
        switch deviceOrientation {
        case UIDeviceOrientation.portrait:
            return AVCaptureVideoOrientation.portrait
        case UIDeviceOrientation.landscapeLeft:
            return AVCaptureVideoOrientation.landscapeRight
        case UIDeviceOrientation.landscapeRight:
            return AVCaptureVideoOrientation.landscapeLeft
        case UIDeviceOrientation.portraitUpsideDown:
            return AVCaptureVideoOrientation.portraitUpsideDown
        default:
            return AVCaptureVideoOrientation.portrait
        }
    }
    

    就在下面一行

    if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) {
    

    添加以下行

    videoConnection.videoOrientation = videoOrientation(for: UIDevice.current.orientation)
    

    注意:如果您的应用仅支持纵向或横向模式,此问题仍然会发生,因为UIDevice.current.orientation 将始终返回支持的方向。为了克服这个问题,您可以使用CoreMotion 来检测设备方向,然后将其传递给videoOrientation(for:) 方法。

    希望这会有所帮助:)

    【讨论】:

    • 对于当前的 swift 版本,我做了一些小改动,但效果很好,我把它放在我的拍照功能中
    【解决方案2】:

    我从@Yodagama 得到了答案,但他没有添加如何检测方向

    if let photoOutputConnection = self.photoOutput.connection(with: .video) {
    
                                // USE the below function HERE
        photoOutputConnection.videoOrientation = videoOrientation()
    }
        
    photoOutput.capturePhoto(with: settings, delegate: self)
    

    检测设备方向的功能:

    func videoOrientation() -> AVCaptureVideoOrientation {
        
        var videoOrientation: AVCaptureVideoOrientation!
        
        let orientation: UIDeviceOrientation = UIDevice.current.orientation
        
        switch orientation {
            
        case .faceUp, .faceDown, .unknown:
            
            // let interfaceOrientation = UIApplication.shared.statusBarOrientation
            
            if let interfaceOrientation = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.windowScene?.interfaceOrientation {
                
                switch interfaceOrientation {
                    
                case .portrait, .portraitUpsideDown, .unknown:
                    videoOrientation = .portrait
                case .landscapeLeft:
                    videoOrientation = .landscapeRight
                case .landscapeRight:
                    videoOrientation = .landscapeLeft
                @unknown default:
                    videoOrientation = .portrait
                }
            }
            
        case .portrait, .portraitUpsideDown:
            videoOrientation = .portrait
        case .landscapeLeft:
            videoOrientation = .landscapeRight
        case .landscapeRight:
            videoOrientation = .landscapeLeft
        @unknown default:
            videoOrientation = .portrait
        }
        
        return videoOrientation
    }
    

    【讨论】:

      【解决方案3】:

      可能的解决方案:将图像保存为 JPEG 而不是 PNG

      这是因为 PNG 不存储方向信息。将照片另存为 JPG,它的方向会正确。

      使用此代码在拍摄图像后立即将图像转换为 JPG(第二行是此处的操作):

      let image = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
      let imageData:NSData = UIImageJPEGRepresentation(image, 0.9)! // 0.9 is compression value: 0.0 is most compressed/lowest quality and 1.0 is least compressed/highest quality
      

      来源+更多信息:https://stackoverflow.com/a/34796890/5700898


      如果这不起作用

      我已经在几个地方编辑了你的代码,看看下面的代码现在是否能如你所愿:

      // initialize saving photo capabilities
      func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafePointer<Void>) {
              if error == nil {
                  print("image saved")
              } else {
                  print("save error: \(error?.localizedDescription)")
              }
      }
      
      // take a photo
      @IBAction func takePhoto(sender: AnyObject) {
      self.fullScreenView.hidden = false
      self.recordButton.enabled = false
      self.takephoto.enabled = false
      self.recordButton.hidden = true
      self.takephoto.hidden = true
      
      session.startRunning()
      
      // customize the quality level or bitrate of the output photo
      session.sessionPreset = AVCaptureSessionPresetPhoto
      
      // add the AVCaptureVideoPreviewLayer to the view and set the view in fullscreen
      fullScreenView.frame = view.bounds
      videoPreviewLayer.frame = fullScreenView.bounds
      fullScreenView.layer.addSublayer(videoPreviewLayer)
      
      // add action to fullScreenView
      gestureFullScreenView = UITapGestureRecognizer(target: self, action: #selector(ViewController.takePhoto(_:)))
      self.fullScreenView.addGestureRecognizer(gestureFullScreenView)
      
      // add action to myView
      gestureView = UITapGestureRecognizer(target: self, action: #selector(ViewController.setFrontpage(_:)))
      self.view.addGestureRecognizer(gestureView)
      
      if (preview == true) {
          if let videoConnection = stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo) {
              // code for photo capture goes here...
      
              stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
                  // process the image data (sampleBuffer) here to get an image file we can put in our view
      
                  if (sampleBuffer != nil) {
                      self.stillImageOutput!.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
              if let videoConnection = self.stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo){
                  videoConnection.videoOrientation = self.interfaceToVideoOrientation()
                  self.stillImageOutput!.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: {
                      (sampleBuffer, error) in
                      let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                      let image = UIImage(data: imageData)
      
                      self.fullScreenView.hidden = true
                      self.fullScreenView.gestureRecognizers?.forEach(self.fullScreenView.removeGestureRecognizer)
                      self.session.stopRunning()
      
                      // save image to the library
                      UIImageWriteToSavedPhotosAlbum(image, self, #selector(ViewController.image(_:didFinishSavingWithError:contextInfo:)), nil)
      
                      self.imageViewBackground = UIImageView(frame: self.view.bounds)
                      self.imageViewBackground.image = image
                      self.imageViewBackground.tag = self.key
      
                      self.view.addSubview(self.imageViewBackground)
                  }
              })
          }
      }
      else {
          preview = true
      }
      }
      

      【讨论】:

      • 我想我把它保存为 JPEG 还是我错了? let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
      • @mafioso 尝试将您的 imageData 声明更改为我在上面所做的声明,我不确定您的是否有效。如果那不能解决您的问题,我会更深入地研究;)。请告诉我。
      • 好的,我会试试的 ;) 但我仍然不知道为什么它在纵向模式下完美地工作,而不是在横向模式下
      • 我应该如何处理 imageData ?
      • 将项目中的这行代码 (let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)) 替换为我在上面的答案中输入的行,@mafioso。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      相关资源
      最近更新 更多