AVFoundation的图像输出仅占屏幕的1/4 1/4

问题描述:

我玩过AVFoundation尝试将滤镜应用于实况视频。我试图将过滤器应用于AVCaptureVideoDataOutput,但输出仅占用了视图的1/4。AVFoundation的图像输出仅占屏幕的1/4 1/4

enter image description here

下面是我的一些相关的代码

捕捉

let availableCameraDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) 
    for device in availableCameraDevices as! [AVCaptureDevice] { 
     if device.position == .Back { 
      backCameraDevice = device 
     } else if device.position == .Front { 
      frontCameraDevice = device 
     } 
    } 

配置输出

private func configureVideoOutput() { 
    videoOutput = AVCaptureVideoDataOutput() 
    videoOutput?.setSampleBufferDelegate(self, queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL)) 
    if session.canAddOutput(videoOutput) { 
     session.addOutput(videoOutput) 
    } 
} 

获取图像

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: 
    CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) { 
    // Grab the pixelbuffer 
    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! 

    // create a CIImage from it, rotate it, and zero the origin 
    var image = CIImage(CVPixelBuffer: pixelBuffer) 
    image = image.imageByApplyingTransform(CGAffineTransformMakeRotation(CGFloat(-M_PI_2))) 
    let origin = image.extent.origin 
    image = image.imageByApplyingTransform(CGAffineTransformMakeTranslation(-origin.x, -origin.y)) 


    self.manualDelegate?.cameraController(self, didOutputImage: image) 
} 

渲染

func cameraController(cameraController: CameraController, didOutputImage image: CIImage) { 
    if glContext != EAGLContext.currentContext() { 
     EAGLContext.setCurrentContext(glContext) 
    } 

    let filteredImage = image.imageByApplyingFilter("CIColorControls", withInputParameters: [kCIInputSaturationKey: 0.0]) 

    var rect = view.bounds 

    glView.bindDrawable() 
    ciContext.drawImage(filteredImage, inRect: rect, fromRect: image.extent) 
    glView.display() 
} 

我期待的Retina显示屏和比例因子造成这一点,但不知道我应该在哪里处理这个。我已经将内容比例因子设置为GLKView,但没有运气。

private var glView: GLKView { 
    // Set in storyboard 
    return view as! GLKView 
} 

glView.contentScaleFactor = glView.bounds.size.width/UIScreen.mainScreen().bounds.size.width * UIScreen.mainScreen().scale 

在开始捕获之前,您设置了哪种格式?你确定视频预览图层正在填满整个屏幕吗? 你有2种方式的avcapture过程中设置的分辨率:

  • 选择AVCaptureDeviceFormat的最高分辨率,通过查找通过现有的采集格式
  • 使用你的sessionPreset财产捕获会话。 Doc here
+0

我没有使用'AVCaptureVideoPreviewLayer'在这种情况下,但OpenGL的。为了捕捉我编辑该部分的帖子。 – sarunw

你的问题是在drawImage功能使用的输出rect

ciContext.drawImage(filteredImage, inRect: rect, fromRect: image.extent) 

图像的程度是实际像素,而视图的边界是点,不是由contentScaleFactor调整,以获得像素。您的设备无疑具有2.0的contentScaleFactor,因此它的尺寸是每个尺寸的1/2。

相反,设置矩形为:

var rect = CGRect(x: 0, y: 0, width: glView.drawableWidth, 
          height: glView.drawableHeight) 

drawableWidthdrawableHeight返回尺寸以像素为单位,占contentScaleFactor。请参阅: https://developer.apple.com/reference/glkit/glkview/1615591-drawablewidth

而且,也没有必要设置glView的contentScaleFactor

+0

这是正确的答案。我遇到了同样的问题,通过在此答案中应用建议的更改而得到解决。谢谢。 – Mikrasya