2012-04-02 5 views
3

Ich schreibe eine benutzerdefinierte Movie Recording App und habe AVAssetWriter und AVAssetWriterInputPixelBufferAdaptor zum Schreiben von Frames in eine Datei implementiert. Im DataOutputDelegate Callback versuche ich einen CIFilter auf den SampleBuffer anzuwenden. Zuerst erhalte ich einen CVPixelBufferRef und dann einen CIImage. Ich habe dann die CIIFilter anzuwenden und das resultierende CIImage greifen:CVPixelBufferRef von CIImage zum Schreiben in Datei erstellen

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... 

Wie würde ich über das Konvertieren gehen, dass CIImage so kann ich:

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

Antwort

9

AKTUALISIERT ANTWORT

Während meiner früheren Methode funktioniert, ich war in der Lage, es zu optimieren, um den Code zu vereinfachen. Es scheint auch etwas schneller zu laufen.

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 

vorherige Antwort

ich implementiert nur die nach dem Pixelpuffer von einem CIImage zu erhalten. Stellen Sie sicher, dass Ihre Pixelformate konsistent sind, da sonst Farbprobleme auftreten. Auch die CFDictionaries sind sehr wichtig. 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 

} 
+2

Dieser Code funktionierte nicht für mich. –

+9

Dies ist eine sehr nützliche Antwort, aber es fehlt mir eine wichtige Information. Was ist [self.filterContext ...]. Wenn ich Ihren Code richtig verstehe, ist dies der Teil, der den CImage tatsächlich zum Pixel Buffer zurückbringt, nach dem ich suche. Können Sie diese Funktion bitte teilen? Vielen Dank! –

+1

@TimBull Ich weiß, es ist ein paar Jahre her, aber für alle, die das in Zukunft sehen können: 'self.filteContext' ist ein' CIContext'-Objekt. Die 'render' Methode macht das' CIllage' zu ​​einem 'CVPixelBuffer' Objekt: https://developer.apple.com/documentation/coreimage/cicontext/1437853-render – halileohalilei

Verwandte Themen