iOS 7+ 上转换 BGRA/UIImage
原始字节的最快方法是什么?数据到 CVPixelBufferRef
?字节是 BGRA 顺序中每个像素 4 个字节。
是否有机会在这里直接转换与将数据复制到辅助存储中?
我考虑过CVPixelBufferCreateWithBytes
但我有预感它正在复制内存......
最佳答案
您必须使用 CVPixelBufferCreate
因为CVPixelBufferCreateWithBytes
不允许使用 Core Video 纹理缓存快速转换为 OpenGL 纹理。我不确定为什么会这样,但至少从 iOS 8 开始就是这样。我用分析器测试了这个,CVPixelBufferCreateWithBytes
每次从缓存中访问 Core Video 纹理时都会调用 texSubImage2D。CVPixelBufferCreate
如果宽度不是 16 的倍数,会做一些有趣的事情,所以如果你打算在 CVPixelBufferGetBaseAddress
上进行 CPU 操作,并且您希望它的布局像 CGImage
或 CGBitmapContext
,您需要将宽度加高直到它是 16 的倍数,或者确保使用 CVPixelBufferGetRowBytes 并将其传递给任何 CGBitmapContext
你创造。
我测试了从 16 到 2048 的所有宽度和高度尺寸组合,只要将它们填充到下一个最高的 16 倍数,内存布局就正确了。
+ (NSInteger) alignmentForPixelBufferDimension:(NSInteger)dim
{
static const NSInteger modValue = 16;
NSInteger mod = dim % modValue;
return (mod == 0 ? dim : (dim + (modValue - mod)));
}
+ (NSDictionary*) pixelBufferSurfaceAttributesOfSize:(CGSize)size
{
return @{ (NSString*)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA),
(NSString*)kCVPixelBufferWidthKey: @(size.width),
(NSString*)kCVPixelBufferHeightKey: @(size.height),
(NSString*)kCVPixelBufferBytesPerRowAlignmentKey: @(size.width * 4),
(NSString*)kCVPixelBufferExtendedPixelsLeftKey: @(0),
(NSString*)kCVPixelBufferExtendedPixelsRightKey: @(0),
(NSString*)kCVPixelBufferExtendedPixelsTopKey: @(0),
(NSString*)kCVPixelBufferExtendedPixelsBottomKey: @(0),
(NSString*)kCVPixelBufferPlaneAlignmentKey: @(0),
(NSString*)kCVPixelBufferCGImageCompatibilityKey: @(YES),
(NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey: @(YES),
(NSString*)kCVPixelBufferOpenGLESCompatibilityKey: @(YES),
(NSString*)kCVPixelBufferIOSurfacePropertiesKey: @{ @"IOSurfaceCGBitmapContextCompatibility": @(YES), @"IOSurfaceOpenGLESFBOCompatibility": @(YES), @"IOSurfaceOpenGLESTextureCompatibility": @(YES) } };
}
有趣的是,如果您从 Core Video 缓存中请求尺寸小于填充尺寸的纹理,它将立即返回一个纹理。不知何故,它下面能够引用原始纹理,但宽度和高度较小。
总而言之,您不能用
CVPixelBufferRef
包装现有内存。使用 CVPixelBufferCreateWithBytes
并有效地使用 Core Video 纹理缓存。您必须使用 CVPixelBufferCreate
并使用 CVPixelBufferGetBaseAddress
.
关于ios - iOS 7+ 上从 BGRA 字节获取 CVPixelBufferRef 的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28102358/