核心图像 - 在CMSampleBufferRef上渲染透明图像会导致其周围出现黑色边框

4
我正在使用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通道。有什么想法吗?
1个回答

8

针对遇到相同问题的开发者:

似乎任何在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);
....

当然,全局的 EAGLContextCIContext 不再需要。


你可以提供一些示例代码吗?我基本上明白正在发生的事情,但是这有点超出我的能力范围。我正在尝试在录制视频时添加水印。所以这正是我需要的。 - chrisallick
@chrisallick 这段代码放在AVCaptureVideoDataOutput的sampleBufferDelegate的captureOutput:didOutputSampleBuffer:fromConnection:方法中。文档:https://developer.apple.com/Library/ios/documentation/AVFoundation/Reference/AVCaptureVideoDataOutput_Class/index.html - Joris Timmerman
它对我没用。我会整理一下我创建的示例并分享它。 - chrisallick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接