我从iPhone的前置摄像头使用AVCaptureSession捕捉帧。 我试着去改变AVCaptureVideoDataOutput的格式,以便它可以捕捉一个24 BPP位图。 此代码为我没有任何问题,一个32 BPP位图:
AVCaptureVideoDataOutput *outputDevice = [[AVCaptureVideoDataOutput alloc] init];
outputDevice.videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey: (id)kCVPixelBufferPixelFormatTypeKey];
[outputDevice setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
然而,当我将其更改为24,它崩溃上线。
outputDevice.videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPixelFormatType_24RGB] forKey: (id)kCVPixelBufferPixelFormatTypeKey];
我怎样才能捕捉到图像中的24 BPP? 为什么会失败* kCVPixelFormatType_24RGB *? 一种解决方法将被转换BMP 32至24,但我还没有找到如何做到这一点。
它崩溃,因为kCVPixelFormatType_24RGB
不支持iPhone。 这在现代的iPhone唯一支持的像素格式是:
- kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
- kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
- kCVPixelFormatType_32BGRA
您可以将任何这些为RGB,虽然BGRA缓冲区是简单的转换。 有多种方法可以做到这一点(这里搜索,并在谷歌的例子),但这里有一个非常简单的方法:
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
@autoreleasepool {
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
uint8_t *sourceBuffer = (uint8_t*)CVPixelBufferGetBaseAddress(imageBuffer);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
int bufferSize = bytesPerRow * height;
uint8_t *bgraData = malloc(bufferSize);
memcpy(bgraData, sourceBuffer, bufferSize);
uint8_t *rgbData = malloc(width * height * 3);
int rgbCount = 0;
for (int i = 0; i < height; i++) {
for (int ii = 0; ii < width; ii+=4) {
int current = (i * height)+ii;
rgbData[rgbCount] = bgraData[current + 2];
rgbData[rgbCount + 1] = bgraData[current + 1];
rgbData[rgbCount + 2] = bgraData[current];
rgbCount+=3;
}
}
//
// Process rgbData
//
free (rgbData);
}
}
顺便说一句,这是8bpp的(不是24 bpp的); 三八位平面构成24位图像,或四个平面使32位图像。 另外值得指出的是,它可能更容易和更快,在大多数情况下,只用32位数据的工作而忽略了Alpha通道,而不是转换为24位。