2012-04-15 4 views
3

Ich benutze AVFoundation, um ein Video zu machen, und ich bin in kCVPixelFormatType_420YpCbCr8BiPlanarFullRange Aufnahmeformat. Ich möchte Graustufenbild direkt von der Y-Ebene des YpCbCr-Formats machen.AVFoundation - Get Graustufenbild von Y-Ebene (kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)

Ich habe versucht, CGContextRef durch Aufruf von CGBitmapContextCreate zu erstellen, aber das Problem ist, dass ich nicht weiß, welchen Farbraum und Pixelformat zu wählen.

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{  
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer,0);   

    /* Get informations about the Y plane */ 
    uint8_t *YPlaneAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0); 
    size_t width = CVPixelBufferGetWidthOfPlane(imageBuffer, 0); 
    size_t height = CVPixelBufferGetHeightOfPlane(imageBuffer, 0); 

    /* the problematic part of code */ 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 

    CGContextRef newContext = CGBitmapContextCreate(YPlaneAddress, 
    width, height, 8, bytesPerRow, colorSpace, kCVPixelFormatType_1Monochrome); 

    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 
    UIImage *grayscaleImage = [[UIImage alloc] initWithCGImage:newImage]; 

    // process the grayscale image ... 
} 

Wenn ich den Code oben laufen, bekam ich diese Fehler:

<Error>: CGBitmapContextCreateImage: invalid context 0x0 
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 192 bytes/row. 

PS: Sorry für mein Englisch.

Antwort

2

Wenn ich mich nicht irre, sollte man nicht über eine gehen. Stattdessen sollten Sie einen Datenprovider und dann direkt das Image erstellen.

Ein weiterer Fehler in Ihrem Code ist die Verwendung der kCVPixelFormatType_1Monochrome Konstante. Es ist eine Konstante in der Videoverarbeitung (AV-Bibliotheken), nicht in Core Graphics (CG-Bibliotheken). Verwenden Sie einfach kCGImageAlphaNone. Das eine einzelne Komponente (grau) pro Pixel benötigt wird (statt drei wie für RGB) wird vom Farbraum abgeleitet.

Es könnte wie folgt aussehen:

CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, YPlaneAdress, 
     height * bytesPerRow, NULL); 
CGImageRef newImage = CGImageCreate(width, height, 8, 8, bytesPerRow, 
     colorSpace, kCGImageAlphaNone, dataProvider, NULL, NO, kCGRenderingIntentDefault); 
CGDataProviderRelease(dataProvider); 
+0

Vielen Dank! Ist es richtig, dass dies der schnellste Weg ist, um ein Graustufenbild von der Kamera zu erhalten? – user961912

+0

@ user961912: Der Zugriff auf den Video-Frame in YpCbCr soll schnell sein, weil es das native Format ist (gemäß einer WWDC-Präsentation). Für die folgenden Schritte kommt es darauf an, was Sie letztendlich mit dem Bild machen. Für mehrere Anwendungen (wie Barcode-Scannen) müssen Sie weder ein CGImage noch ein UIImage erstellen. – Codo

+0

Hey Codo, Vielen Dank für diese Antwort! Ich versuche, ein bisschen "dasselbe" Ergebnis zu erreichen, der Unterschied ist, dass ich versuche, den Graustufeneffekt zu erzielen, auf jedem Frame (Live-Video-Stream), jede Chance, dass Sie mich in die richtige Richtung lenken können? –