当前位置 : 主页 > 手机开发 > ios >

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

来源:互联网 收集:自由互联 发布时间:2021-06-11
我正在尝试使用AVFoundation的AVCaptureVideoDataOutput在我正在录制的视频上添加水印/徽标. 我的类被设置为sampleBufferDelegate并接收CMSamplebufferRefs.我已经将一些效果应用于CMSampleBufferRefs CVPixelB
我正在尝试使用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.
有任何想法吗?

对于遇到相同问题的开发人员:

看起来在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.

网友评论