-->

从iPhone照相机捕获24 BPP位图图像(AVCaptureSession)(Capturing

2019-10-29 12:59发布

我从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,但我还没有找到如何做到这一点。

Answer 1:

它崩溃,因为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位。



文章来源: Capturing images in 24 bpp bitmap from iPhone camera (AVCaptureSession)