MTKView-调整纹理大小以填充视图

时间:2019-02-21 23:01:57

标签: ios swift avfoundation metal metalkit

我对Metal还是很陌生,但是一直在努力遵循Apple的AVCamFilter示例项目。该项目演示了如何使用MTKView作为AVCaptureSession的预览。

我一直无法弄清楚如何使我的MTKView呈现“全屏”(特别是在iPhone X,XS和第三代iPad Pro上)。在情节提要中正确设置了我的约束后,我的相机预览将缩放为其他宽高比,而不是全屏。

作为测试,我进行设置;

self.clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)

在我的MTKView的初始化中,确认MTKView的大小正确(我可以在有问题的区域看到红色背景,但是我的相机预览无法伸展到整个屏幕)。

我相信我的问题存在于此计算中;

// Calculate scale.
if textureWidth > 0 && textureHeight > 0 {
  switch textureRotation {
    case .rotate0Degrees, .rotate180Degrees:
      scaleX = Float(internalBounds.width / CGFloat(textureWidth))
      scaleY = Float(internalBounds.height / CGFloat(textureHeight))

    case .rotate90Degrees, .rotate270Degrees:
      scaleX = Float(internalBounds.width / CGFloat(textureHeight))
      scaleY = Float(internalBounds.height / CGFloat(textureWidth))
   }
}

// Resize aspect ratio.
resizeAspect = min(scaleX, scaleY)
if scaleX < scaleY {
  scaleY = scaleX / scaleY
  scaleX = 1.0
} else {
  scaleX = scaleY / scaleX
  scaleY = 1.0
}

在测试环境中,纹理尺寸为2400x1800,内部边界为834x1194。虽然我认识到宽高比的差异,但我仍在尝试找出正确的数学方法,以使纹理填充整个显示器(即使这意味着缩放比例稍小,并且我会损失一些侧面的纹理)。

有人可以建议吗?谢谢!

2 个答案:

答案 0 :(得分:0)

Open PreviewMetalView.swift

Replace following lines:
let width = CVPixelBufferGetWidth(previewPixelBuffer)
let height = CVPixelBufferGetHeight(previewPixelBuffer)

with following lines: 
let previewViewWidth = Int(self.frame.size.width)
let previewViewheight = Int(self.frame.size.height)
let isPortrait = previewViewheight > previewViewWidth
let width = isPortrait ? previewViewheight : previewViewWidth
let height = isPortrait ? previewViewWidth : previewViewheight

答案 1 :(得分:0)

  comment                             label

Bromwell High is a cartoon comedy..     1
Homelessness (or Houselessness ..       1
Brilliant over-acting by Lesley A...    1
This is easily the most underrated ..   1
This is not the typical Mel Broo...     1

替换为

// Resize aspect ratio.
resizeAspect = min(scaleX, scaleY)

if scaleX < scaleY {
  scaleY = scaleX / scaleY
  scaleX = 1.0
} else {
  scaleX = scaleY / scaleX
  scaleY = 1.0
}