如何 resize/scale 一个 MTLTexture

How to resize/scale an MTLTexture

我有一个 MTLTexture,它的大小与它出现在 MTLView 中的大小相同。但是,我正在将纹理写入 AVAssetWriterInputPixelBufferAdaptor 以录制需要纹理为标准的视频视频大小,即 1280x720。

目前我正在使用MTLRegionMake2D指定要提取的纹理区域。在宽度较长的 phone 上,裁剪的效果并不那么明显。但是在形状和大小更正方形的 iPad 上,裁剪很明显。理想情况下,我会先将纹理调整为与视频相同的宽度或高度,然后裁剪其余部分(而不是仅仅裁剪)。

调整 MTLTexture 大小的合适方法是什么?

示例代码:

guard let pixelBufferPool = assetWriterPixelBufferInput.pixelBufferPool else { return }

var maybePixelBuffer: CVPixelBuffer? = nil
let status  = CVPixelBufferPoolCreatePixelBuffer(nil, pixelBufferPool, &maybePixelBuffer)
if status != kCVReturnSuccess { return }

guard let pixelBuffer = maybePixelBuffer else { return }

CVPixelBufferLockBaseAddress(pixelBuffer, [])
let pixelBufferBytes = CVPixelBufferGetBaseAddress(pixelBuffer)!

let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let region = MTLRegionMake2D(0, 0, Int(videoSize.width), Int(videoSize.height))

texture.getBytes(pixelBufferBytes, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)

let frameTime = CACurrentMediaTime()
let presentationTime = CMTimeMakeWithSeconds(frameTime, 240)
assetWriterPixelBufferInput.append(pixelBuffer, withPresentationTime: presentationTime)

CVPixelBufferUnlockBaseAddress(pixelBuffer, [])

最后我用了MPSImageLanczosScale缩放贴图,见:

Apple 文档: https://developer.apple.com/documentation/metalperformanceshaders/mpsimagelanczosscale

示例:

重新缩放后,我仍然需要使用一个区域来裁剪剩余部分。我有一些逻辑来检测 portrait/landscape,平板电脑或 phone 来确定合适的作物。在我的例子中(对于纵向),我选择垂直居中用于瘦身设备 (phone) 裁剪 top/bottom,而水平居中用于宽屏设备(平板电脑)裁剪 left/right。对景观有类似的逻辑,但相反。