如何 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。对景观有类似的逻辑,但相反。
我有一个 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。对景观有类似的逻辑,但相反。