我需要在实时视频上应用滤镜,我正尝试在 Metal 中进行。
但是我在将过滤器编码到目标过滤器后将 MTLTexture 转换为 CVPixelBuffer 时遇到了问题。引用 ( https://github.com/oklyc/MetalCameraSample-master-2 )
这是我的代码。
if let pixelBuffer = pixelBuffer {
CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.init(rawValue: 0))
let region = MTLRegionMake2D(0, 0, Int(currentDrawable.layer.drawableSize.width), Int(currentDrawable.layer.drawableSize.height))
let bytesPerPixel = 4;
let bytesPerRow = CGFloat(bytesPerPixel) * currentDrawable.layer.drawableSize.width
let tempBuffer = CVPixelBufferGetBaseAddress(pixelBuffer)
destinationTexture.getBytes(tempBuffer!, bytesPerRow: Int(bytesPerRow), from: region1, mipmapLevel: 0)
let image = self.imageFromCVPixelBuffer(buffer: pixelBuffer)
CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.init(rawValue: 0))
}
imageFromCVPixelBuffer 方法如下所示。
func imageFromCVPixelBuffer(buffer: CVPixelBuffer) -> UIImage {
let ciimage = CIImage(cvPixelBuffer: buffer)
let context = CIContext(options: nil)
let cgimgage = context.createCGImage(ciimage, from: CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(buffer), height: CVPixelBufferGetHeight(buffer)))
let uiimage = UIImage(cgImage: cgimgage!)
return uiimage
}
这是通过 Metal 渲染图像的屏幕截图
这是将 MTLTexture 转换为 CVPixelBuffer 的同一图像的屏幕截图。
需要将MTLtexture转换成CVPixelBuffer,写入AVAssetWriter,然后保存到Library。
最佳答案
不要像那样自己计算 bytesPerRow
。它被传递给 Metal,让 Metal 知道如何排列行。您希望 Metal 按照 CVPixelBuffer
期望的方式排列它们。因此,您应该使用 CVPixelBufferGetBytesPerRow()
来确定该值。
关于ios - 如何将 MTLTexture 转换为 CVpixelBuffer 以写入 AVAssetWriter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44842661/