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 アルファを描画していないようです。何か案は?

4

1 に答える 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);
....

もちろん、globalEAGLContextと はCIContextもう必要ありません。

于 2014-08-20T12:45:15.590 に答える