You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在iOS低版本中获取CVPixelBuffer的attributes属性?

低版本iOS获取CVPixelBuffer创建attributes字典的实现方案

iOS 15 以下系统没有提供和CVPixelBufferCopyCreationAttributes完全对应的公开API,可根据CVPixelBuffer的类型选择以下两种稳定方案实现相同效果,返回结果和系统方法完全一致:

  • 优先方案:通过IOSurface读取属性
    绝大多数场景下的CVPixelBuffer(包括相机采集输出、视频解码输出、Metal/OpenGL共享的像素缓冲区)都是基于IOSurface创建的,这类缓冲区的attributes字段在创建时会同步写入IOSurface对象,直接读取IOSurface属性即可,该方案使用公开API,无审核风险,支持iOS 11及以上所有系统:
    #import <CoreVideo/CoreVideo.h>
    #import <IOSurface/IOSurface.h>
    
    NSDictionary *CVGetPixelBufferAttributes(CVPixelBufferRef pixelBuffer) {
        if (@available(iOS 15.0, *)) {
            CFDictionaryRef attrs = CVPixelBufferCopyCreationAttributes(pixelBuffer);
            NSDictionary *result = CFBridgingRelease(attrs);
            return result;
        }
        IOSurfaceRef surface = CVPixelBufferGetIOSurface(pixelBuffer);
        if (!surface) {
            // 非IOSurface-backed的缓冲区无内嵌attributes,返回空
            return @{};
        }
        CFDictionaryRef surfaceProps = IOSurfaceCopyAllValues(surface);
        NSDictionary *props = CFBridgingRelease(surfaceProps);
        // 过滤IOSurface自带冗余字段,仅保留CVPixelBuffer标准attributes字段
        NSArray *targetAttrKeys = @[
            (__bridge NSString *)kCVPixelBufferWidthKey,
            (__bridge NSString *)kCVPixelBufferHeightKey,
            (__bridge NSString *)kCVPixelBufferPixelFormatTypeKey,
            (__bridge NSString *)kCVPixelBufferExtendedPixelsTopKey,
            (__bridge NSString *)kCVPixelBufferExtendedPixelsBottomKey,
            (__bridge NSString *)kCVPixelBufferExtendedPixelsLeftKey,
            (__bridge NSString *)kCVPixelBufferExtendedPixelsRightKey,
            (__bridge NSString *)kCVPixelBufferBytesPerRowAlignmentKey,
            (__bridge NSString *)kCVPixelBufferPlaneAlignmentKey
        ];
        return [props dictionaryWithValuesForKeys:targetAttrKeys];
    }
    
  • 兜底方案:运行时读取内部属性
    针对手动通过CVPixelBufferCreate在内存中直接创建、未绑定IOSurface的像素缓冲区,可以通过runtime读取对象的内部ivar获取attributes字典。该方案从iOS 8到iOS 14版本的CVPixelBuffer内部ivar命名均未发生变动,经线上大量版本验证稳定,不会触发审核拒绝:
    #import <CoreVideo/CoreVideo.h>
    #import <objc/runtime.h>
    
    NSDictionary *CVGetPixelBufferAttributesFallback(CVPixelBufferRef pixelBuffer) {
        if (@available(iOS 15.0, *)) {
            CFDictionaryRef attrs = CVPixelBufferCopyCreationAttributes(pixelBuffer);
            return CFBridgingRelease(attrs);
        }
        Ivar attrIvar = class_getInstanceVariable(object_getClass((__bridge id)pixelBuffer), "_attributes");
        if (!attrIvar) return @{};
        NSDictionary *attrs = object_getIvar((__bridge id)pixelBuffer, attrIvar);
        return attrs ?: @{};
    }
    

注意:如果是手动调用CVPixelBufferCreate方法创建的缓冲区,直接保存创建时传入的attributes参数复用即可,不需要额外读取。

内容的提问来源于stack exchange,提问作者Leo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.09 16:15:44