来自 CMSampleBufferRef 的图像始终为白色

Posted

技术标签:

【中文标题】来自 CMSampleBufferRef 的图像始终为白色【英文标题】:Image from CMSampleBufferRef is always white 【发布时间】:2018-09-24 18:00:16 【问题描述】:

我正在尝试使用 startCaptureWithHandler 从 replaykit 获取每一帧。

startCaptureWithHandler 返回一个我需要转换为图像的 CMSampleBufferRef。

我使用这种方法转换为 UIImage 但它总是白色的。

- (UIImage *) imageFromSampleBuffer3:(CMSampleBufferRef) sampleBuffer

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
    CVPixelBufferRef pxbuffer = NULL;
    CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, &pxbuffer);

    CVPixelBufferLockFlags flags = (CVPixelBufferLockFlags)0;
    CVPixelBufferLockBaseAddress(pxbuffer, flags);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
//    CGContextRef context = CGBitmapContextCreate(pxdata, width, height, 8, CVPixelBufferGetBytesPerRow(pxbuffer), rgbColorSpace, kCGImageAlphaPremultipliedFirst);
    CGContextRef context = CGBitmapContextCreate(pxdata, width, height, 8, CVPixelBufferGetBytesPerRow(pxbuffer), rgbColorSpace, kCGImageAlphaPremultipliedFirst);

    CGImageRef quartzImage = CGBitmapContextCreateImage(context);

    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pxbuffer, flags);

    UIImage *image = [UIImage imageWithCGImage:quartzImage scale:1.0f orientation:UIImageOrientationRight];

    CGImageRelease(quartzImage);
    return image;

谁能告诉我哪里出错了?

【问题讨论】:

【参考方案1】:

sampleBuffer 是 420f 格式,它有 2 个平面。 对于锁定内存,CVPixelBufferLockBaseAddress(imageBuffer, 0 then 1)。 对于获取 Y 平面数据,CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0)。 对于 UV 平面数据,CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 1)。 不要忘记解锁记忆。我不确定如何将 YUV 转换为 RGB。

在您的代码中,您不会从 imageBuffer 读取图像数据。 你只在没有图像数据的 pxbuffer 和 pxdata 上工作。

【讨论】:

谢谢...我明天检查一下,如果它有效,请报告。

以上是关于来自 CMSampleBufferRef 的图像始终为白色的主要内容,如果未能解决你的问题,请参考以下文章

来自 CMSampleBufferRef 的 NSData 或字节

从 CMSampleBufferRef 获取当前视频时长

如何将 CMSampleBufferRef 转换为 NSData

缩放和裁剪 CMSampleBufferRef

从 CMSampleBufferRef 转换的 UIImage,导致 UIImage 无法正确渲染

如何在 Android 的 LISTVIEW 中为每个原​​始图像添加不同的图像?