在录制视频时将动态文本渲染到CVPixelBufferRef上

bar*_*dog 6 objective-c core-image avfoundation core-video ios

我正在使用AVCaptureVideoDataOutput和记录视频和音频,AVCaptureAudioDataOutput并且在captureOutput:didOutputSampleBuffer:fromConnection:委托方法中,我想在我从视频连接接收的每个单独的样本缓冲区上绘制文本.文本随着每一帧(它是一个秒表标签)而变化,我希望将其记录在捕获的视频数据之上.

这是我到目前为止所能提出的:

//1.
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

//2.   
UIImage *textImage = [self createTextImage];
CIImage *maskImage = [CIImage imageWithCGImage:textImage.CGImage];

//3.
CVPixelBufferLockBaseAddress(pixelBuffer, 0); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSDictionary *options = [NSDictionary dictionaryWithObject:(__bridge id)colorSpace forKey:kCIImageColorSpace];
CIImage *inputImage = [CIImage imageWithCVPixelBuffer:pixelBuffer options:options];

//4.
CIFilter *filter = [CIFilter filterWithName:@"CIBlendWithMask"];
[filter setValue:inputImage forKey:@"inputImage"];
[filter setValue:maskImage forKey:@"inputMaskImage"];
CIImage *outputImage = [filter outputImage];
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);

//5.   
[self.renderContext render:outputImage toCVPixelBuffer:pixelBuffer bounds:[outputImage extent] colorSpace:CGColorSpaceCreateDeviceRGB()];

//6.
[self.pixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:timestamp];
Run Code Online (Sandbox Code Playgroud)
  1. 在这里,我抓住像素缓冲区,就像馅饼一样容易.
  2. 我使用核心图形将文本写入空白的UIImage(就是createTextImage这样.我能够验证这一步是否有效;我保存了一个带有文本的图像到我的照片中.
  3. 我从像素缓冲区创建一个CGImage.
  4. 我制作了一个CIFilter CIBlendWithMask,将输入图像设置为从原始像素缓冲区创建的输入图像,输入掩码设置为CIImage从图像上绘制的输入图像.
  5. 最后,我将滤镜输出图像渲染到pixelBuffer.这CIContext是事先创建的[CIContext contextWithOptions:nil];.
  6. 毕竟,我将像素缓冲区附加到我pixelBufferAdaptor的适当的时间戳.

在录制结束时保存的视频没有可见的变化,即没有在像素缓冲区上绘制掩模图像.

任何人都知道我在哪里错了?我已经坚持了好几天,任何帮助都会如此受到赞赏.

编辑:

- (UIImage *)createTextImage {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height), NO, 1.0);
    NSMutableAttributedString *timeStamp = [[NSMutableAttributedString alloc]initWithString:self.timeLabel.text attributes:@{NSForegroundColorAttributeName:self.timeLabel.textColor, NSFontAttributeName: self.timeLabel.font}];
    NSMutableAttributedString *countDownString = [[NSMutableAttributedString alloc]initWithString:self.cDownLabel.text attributes:@{NSForegroundColorAttributeName:self.cDownLabel.textColor, NSFontAttributeName:self.cDownLabel.font}];
    [timeStamp drawAtPoint:self.timeLabel.center];
    [countDownString drawAtPoint:self.view.center];
    UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return blank;
}
Run Code Online (Sandbox Code Playgroud)

Ban*_*ngs 4

你想要像下面这样吗? 在此输入图像描述

CIBlendWithMask您应该使用而不是使用CISourceOverCompositing,试试这个:

//4.
CIFilter *filter = [CIFilter filterWithName:@"CISourceOverCompositing"];
[filter setValue:maskImage forKey:kCIInputImageKey];
[filter setValue:inputImage forKey:kCIInputBackgroundImageKey];
CIImage *outputImage = [filter outputImage];
Run Code Online (Sandbox Code Playgroud)