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