我目前正在使用Metal进行实时过滤。 在定义了我的CIImage之后,我将图像渲染为MTLTexture。
下面是我的渲染代码。 context
是由Metal支持的CIContext;
targetTexture
是附加到我的MTKView实例的currentDrawable
属性的纹理的别名:
context?.render(drawImage, to: targetTexture, commandBuffer: commandBuffer, bounds: targetRect, colorSpace: colorSpace)
它正确渲染,因为我可以看到金属视图上显示的图像。
问题是在渲染图像(并显示图像)之后,我想提取CVPixelBuffer并使用AVAssetWriter类将其保存到磁盘。
另一种选择是拥有两个渲染步骤,一个渲染到纹理,另一个渲染到CVPixelBuffer。 (但是不清楚如何创建这样的缓冲区,或者两个渲染步骤对帧速率的影响)
任何帮助将不胜感激,谢谢!
答案 0 :(得分:0)
您可以尝试从MTLTexture复制原始数据,如下所示:
var outPixelbuffer: CVPixelBuffer?
if let datas = targetTexture.texture.buffer?.contents() {
CVPixelBufferCreateWithBytes(kCFAllocatorDefault, targetTexture.width,
targetTexture.height, kCVPixelFormatType_64RGBAHalf, datas,
targetTexture.texture.bufferBytesPerRow, nil, nil, nil, &outPixelbuffer);
}
答案 1 :(得分:-1)
+ (void)getPixelBufferFromBGRAMTLTexture:(id<MTLTexture>)texture result:(void(^)(CVPixelBufferRef pixelBuffer))block
{
CVPixelBufferRef pxbuffer = NULL;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
size_t imageByteCount = texture.width * texture.height * 4;
void *imageBytes = malloc(imageByteCount);
NSUInteger bytesPerRow = texture.width * 4;
MTLRegion region = MTLRegionMake2D(0, 0, texture.width, texture.height);
[texture getBytes:imageBytes bytesPerRow:bytesPerRow fromRegion:region mipmapLevel:0];
CVPixelBufferCreateWithBytes(kCFAllocatorDefault,texture.width,texture.height,kCVPixelFormatType_32BGRA,imageBytes,bytesPerRow,NULL,NULL,(__bridge CFDictionaryRef)options,&pxbuffer);
if (block) {
block(pxbuffer);
}
CVPixelBufferRelease(pxbuffer);
free(imageBytes);
}