MTKView - Изменение размера текстуры, чтобы заполнить вид

Я очень новичок в металле, но усердно работаю, чтобы следовать примеру проекта 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 ответа

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

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

Заменить

      // Resize aspect ratio.
// For AspectFill Screen scaleX > scaleY
// For AspectFit Screen scaleX < scaleY
    
resizeAspect = min(scaleX, scaleY)
if scaleX > scaleY {
   scaleY = scaleX / scaleY
   scaleX = 1.0
} else {
   scaleX = scaleY / scaleX
  scaleY = 1.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
Другие вопросы по тегам