我正在尝试使用AVFoundation的AVCaptureVideoDataOutput在我正在录制的视频上添加水印/徽标。 我的类被设置为sampleBufferDelegate并接收CMSamplebufferRefs。我已经将一些效果应用于CMSampleBufferRefs CVPixelBuffer并将其传递回AVAssetWriter。
左上角的徽标使用透明的PNG传送。 我遇到的问题是,一旦写入视频,UIImage的透明部分就是黑色。 任何人都知道我做错了什么或者忘记了什么?
以下代码段:
//somewhere in the init of the class;
_eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
_ciContext = [CIContext contextWithEAGLContext:_eaglContext
options: @{ kCIContextWorkingColorSpace : [NSNull null] }];
//samplebufferdelegate method:
- (void) captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
....
UIImage *logoImage = [UIImage imageNamed:@"logo.png"];
CIImage *renderImage = [[CIImage alloc] initWithCGImage:logoImage.CGImage];
CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
[_ciContext render:renderImage
toCVPixelBuffer:pixelBuffer
bounds: [renderImage extent]
colorSpace:cSpace];
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
CGColorSpaceRelease(cSpace);
....
}
看起来CIContext没有绘制CIImages alpha。 有什么想法吗?
答案 0 :(得分:7)
对于遇到同样问题的开发者:
看起来任何在GPU上呈现并写入视频的内容最终会在视频中形成黑洞。 取而代之的是,我删除了上面的代码,创建了一个CGContextRef,就像编辑图像时一样,并绘制了上下文。
代码:
....
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
CGContextRef context = CGBitmapContextCreate(CVPixelBufferGetBaseAddress(pixelBuffer),
CVPixelBufferGetWidth(pixelBuffer),
CVPixelBufferGetHeight(pixelBuffer),
8,
CVPixelBufferGetBytesPerRow(pixelBuffer),
CGColorSpaceCreateDeviceRGB(),
(CGBitmapInfo)
kCGBitmapByteOrder32Little |
kCGImageAlphaPremultipliedFirst);
CGRect renderBounds = ...
CGContextDrawImage(context, renderBounds, [overlayImage CGImage]);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
CGColorSpaceRelease(cSpace);
....
当然,不再需要全局EAGLContext
和CIContext
。