【问题标题】:Create CVPixelBufferRef from CIImage for Writing to File从 CIImage 创建 CVPixelBufferRef 以写入文件
【发布时间】:2012-04-16 14:13:23
【问题描述】:

我正在编写一个自定义电影录制应用程序,并实现了 AVAssetWriter 和 AVAssetWriterInputPixelBufferAdaptor 用于将帧写入文件。在 DataOutputDelegate 回调中,我尝试将 CIFilter 应用于 sampleBuffer。首先我得到一个 CVPixelBufferRef 然后创建一个 CIImage。然后我应用 CIIFilter 并获取生成的 CIImage:

    CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);

    CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
    CIFilter *hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"];
    [hueAdjust setDefaults];
    [hueAdjust setValue: image forKey: @"inputImage"];
    [hueAdjust setValue: [NSNumber numberWithFloat: 2.094]
                 forKey: @"inputAngle"];

    CIImage *result = [hueAdjust valueForKey: @"outputImage"];

    CVPixelBufferRef newBuffer = //Convert CIImage...

我将如何转换 CIImage 以便我可以:

    [self.filteredImageWriter appendPixelBuffer:newBuffer withPresentationTime:lastSampleTime];

【问题讨论】:

    标签: objective-c ios core-image avassetwriter core-video


    【解决方案1】:

    更新答案

    虽然我以前的方法有效,但我能够对其进行调整以简化代码。它似乎也运行得更快。

    samplePixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(samplePixelBuffer, 0); // NOT SURE IF NEEDED // NO PERFORMANCE IMPROVEMENTS IF REMOVED
    
    NSDictionary *options = [NSDictionary dictionaryWithObject:(__bridge id)rgbColorSpace forKey:kCIImageColorSpace];                
    outputImage = [CIImage imageWithCVPixelBuffer:samplePixelBuffer options:options];
    
    //-----------------
    // FILTER OUTPUT IMAGE
    
    @autoreleasepool {
    
        outputImage = [self applyEffectToCIImage:outputImage dict:dict];
    
    }
    CVPixelBufferUnlockBaseAddress(samplePixelBuffer, 0); // NOT SURE IF NEEDED // NO PERFORMANCE IMPROVEMENTS IF REMOVED
    
    //-----------------
    // RENDER OUTPUT IMAGE BACK TO PIXEL BUFFER
    
    [self.filterContext render:outputImage toCVPixelBuffer:samplePixelBuffer bounds:[outputImage extent] colorSpace:CGColorSpaceCreateDeviceRGB()]; // DOES NOT SEEM TO WORK USING rgbColorSpace
    

    以前的答案

    我刚刚实现了以下从 CIImage 获取像素缓冲区。确保您的像素格式一致,否则您将遇到颜色问题。 CFDictionaries 也非常重要。 http://allmybrain.com/2011/12/08/rendering-to-a-texture-with-ios-5-texture-cache-api/

    CFDictionaryRef empty = CFDictionaryCreate(kCFAllocatorDefault, // EMPTY IOSURFACE DICT
                                               NULL,
                                               NULL,
                                               0,
                                               &kCFTypeDictionaryKeyCallBacks,
                                               &kCFTypeDictionaryValueCallBacks);
    CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                             1,
                                                             &kCFTypeDictionaryKeyCallBacks,
                                                             &kCFTypeDictionaryValueCallBacks);
    
    CFDictionarySetValue(attributes,kCVPixelBufferIOSurfacePropertiesKey,empty);
    
    CVPixelBufferRef pixelBuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, 
                                          outputImage.extent.size.width, 
                                          outputImage.extent.size.height, 
                                          kCVPixelFormatType_32BGRA, 
                                          attributes, 
                                          &pixelBuffer);
    
    if (status == kCVReturnSuccess && pixelBuffer != NULL) {
    
        CVPixelBufferLockBaseAddress(pixelBuffer, 0); // NOT SURE IF NEEDED // KEPT JUST IN CASE
        [self.filterContext render:outputImage toCVPixelBuffer:pixelBuffer bounds:[outputImage extent] colorSpace:CGColorSpaceCreateDeviceRGB()];
        CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); // NOT SURE IF NEEDED // KEPT JUST IN CASE
    
    }
    

    【讨论】:

    • 这是一个非常有用的答案,但它对我来说缺少一条关键信息。什么是 [self.filterContext...]。如果我正确理解您的代码,这就是实际将 CIImage 渲染回我正在寻找的像素缓冲区的部分。请问可以分享一下这个功能吗?谢谢!
    • @TimBull 我知道这已经有几年了,但对于将来可能会看到这一点的任何人:self.filteContext 是一个CIContext 对象。 render 方法将 CIImage 渲染为 CVPixelBuffer 对象:developer.apple.com/documentation/coreimage/cicontext/…
    • swift 中的示例?
    • @halileohalilei 你能在 Swift 中提供完整的例子,并且很热能得到那个上下文吗?是CIImage的形式吗?
    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    • 2018-11-29
    • 2012-02-24
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多