【问题标题】:iOS Camera Video Live Preview Is Offset To Picture TakeniOS 相机视频实时预览与拍摄的照片有偏移
【发布时间】:2014-10-19 04:05:08
【问题描述】:

我正在使用相机。

摄像头向用户呈现实时提要,当用户单击时,会创建图像并将其传递给用户。

问题是图像被设计到最高位置,高于实时预览显示的位置。

你知道如何调整相机的框架,使实时视频源的顶部与他们要拍摄的照片的顶部相匹配吗?

我认为这可以做到这一点,但事实并非如此。这是我当前的相机帧代码:

 //Add the device to the session, get the video feed it produces and add it to the video feed layer
    func initSessionFeed()
    {
_session = AVCaptureSession()
        _session.sessionPreset = AVCaptureSessionPresetPhoto
        updateVideoFeed()

        _videoPreviewLayer = AVCaptureVideoPreviewLayer(session: _session)
        _videoPreviewLayer.frame = CGRectMake(0,0, self.frame.width, self.frame.width) //the live footage IN the video feed view
        _videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        self.layer.addSublayer(_videoPreviewLayer)//add the footage from the device to the video feed layer
    }

    func initOutputCapture()
    {
        //set up output settings
        _stillImageOutput = AVCaptureStillImageOutput()
        var outputSettings:Dictionary = [AVVideoCodecJPEG:AVVideoCodecKey]
        _stillImageOutput.outputSettings = outputSettings
        _session.addOutput(_stillImageOutput)
        _session.startRunning()
    }

    func configureDevice()
    {
        if _currentDevice != nil
        {
            _currentDevice.lockForConfiguration(nil)
            _currentDevice.focusMode = .Locked
            _currentDevice.unlockForConfiguration()
        }
    }

    func captureImage(callback:(iImage)->Void)
    {
        if(_captureInProcess == true)
        {
            return
        }
        _captureInProcess = true

        var videoConnection:AVCaptureConnection!
        for connection in _stillImageOutput.connections
        {
            for port in (connection as AVCaptureConnection).inputPorts
            {
                if (port as AVCaptureInputPort).mediaType == AVMediaTypeVideo
                {
                    videoConnection = connection as AVCaptureConnection
                    break;
                }

                if videoConnection != nil
                {
                    break;
                }
            }
        }

        if videoConnection  != nil
        {
            _stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection)
            {
                (imageSampleBuffer : CMSampleBuffer!, _) in
                let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
                var pickedImage = UIImage(data: imageDataJpeg, scale: 1)
                UIGraphicsBeginImageContextWithOptions(pickedImage.size, false, pickedImage.scale)
                pickedImage.drawInRect(CGRectMake(0, 0, pickedImage.size.width, pickedImage.size.height))
                pickedImage = UIGraphicsGetImageFromCurrentImageContext() //this returns a normalized image
                if(self._currentDevice == self._frontCamera)
                {
                    var context:CGContextRef = UIGraphicsGetCurrentContext()
                    pickedImage = UIImage(CGImage: pickedImage.CGImage, scale: 1.0, orientation: .UpMirrored)
                    pickedImage.drawInRect(CGRectMake(0, 0, pickedImage.size.width, pickedImage.size.height))
                    pickedImage = UIGraphicsGetImageFromCurrentImageContext()
                }
                UIGraphicsEndImageContext()
                var image:iImage = iImage(uiimage: pickedImage)
                self._captureInProcess = false
                callback(image)
            }
        }
    }

如果我通过提高 y 值来调整 AVCaptureVideoPreviewLayer 的知名度,我只会得到一个显示偏移量的黑条。我很好奇为什么最上面的视频帧与我的输出图像不匹配。

我确实“裁剪”了相机,因此它是一个完美的正方形,但是为什么实时相机馈送的顶部不是实际顶部(因为图像默认为相机馈送未显示的更高位置)

更新:

这是我所说的前后的屏幕截图

之前: Before image这是实时提要显示的内容

之后: After image这是用户点击拍照时的结果图片

【问题讨论】:

  • 所以您希望结果图像显示在屏幕顶部,与您在实时供稿中看到的完全一样?
  • 我希望相机馈送(之前)看起来像用户拍照时提供给用户的内容(之后)。
  • 神奇的 AV 摄像头示例代码:drivecurrent.com/devops/…

标签: ios swift camera uikit avfoundation


【解决方案1】:

而不是

_videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

你可以试试

_videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspect

一般来说,预览和捕获的图像的宽度和高度必须匹配。您可能需要对预览或最终图像进行更多“裁剪”,或两者兼而有之。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,这段代码对我有用:

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    var bounds = UIScreen.mainScreen().bounds
    
    previewLayer?.bounds = bounds
    previewLayer?.videoGravity = AVLayerVideoGravityResize
    previewLayer?.position = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))
    self.cameraPreview.layer.addSublayer(previewLayer)
    captureSession.startRunning()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多