如何在Swift中初始化CVPixelBufferRef

11

我们以前会像下面这样初始化CVPixelBufferRef。

  CVPixelBufferRef pxbuffer = NULL;

但在Swift中我们无法使用NULL,因此我们尝试了以下方法,但XCODE当然要求我们初始化才能使用它

let pxbuffer: CVPixelBufferRef

但是怎么做呢?

在 Obj_C 中,我们是这样创建缓冲区的,但正如我上面试图解释的那样,当转换为 Swift 时,我在第一行就被卡住了。

 CVPixelBufferRef pxbuffer = NULL;

CVPixelBufferCreate(kCFAllocatorDefault, picGenislik,
                    frameHeight, kCVPixelFormatType_32ARGB, (__bridge         CFDictionaryRef) options,
                    &pxbuffer);

任何接受NULL / nil的引用都是可选变量,请检查我的答案,我已经创建了一个可选的pixelBuffer - Inder Kumar Rathore
3个回答

11

使用CVPixelBufferCreate(_:_:_:_:_:_:)创建对象。

以下是一些示例代码,希望这能帮到你。同时请阅读在Swift中使用旧的C API

var keyCallBack: CFDictionaryKeyCallBacks
var valueCallBacks: CFDictionaryValueCallBacks

var empty: CFDictionaryRef = CFDictionaryCreate(kCFAllocatorDefault, nil, nil, 0, &keyCallBack, &valueCallBacks)

var attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
    1,
    &keyCallBack,
    &valueCallBacks);


var iOSurfacePropertiesKey = kCVPixelBufferIOSurfacePropertiesKey

withUnsafePointer(&iOSurfacePropertiesKey) { unsafePointer in
    CFDictionarySetValue(attributes, unsafePointer, empty)
}

var width = 10
var height = 12
var pixelBuffer: CVPixelBufferRef? = nil
var status: CVReturn = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, attributes, &pixelBuffer)

我尝试了CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32ARGB, options, pxbuffer),但是没有成功。它不喜欢pxbuffer。 - Hope
您最新的更新让我进展了一些,谢谢。但是,我想知道为什么需要那么多的代码来打开内存中的像素计算位置。也许是因为我不太喜欢阅读。 - Hope

5

这里有另一种方法可以实现(Swift 3):

var pixelBuffer: UnsafeMutablePointer<CVPixelBuffer?>!
if pixelBuffer == nil {
pixelBuffer = UnsafeMutablePointer<CVPixelBuffer?>.allocate(capacity: MemoryLayout<CVPixelBuffer?>.size)
}
CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, attributes, pixelBuffer)

然后您可以像这样访问缓冲对象:
pixelBuffer.pointee

编辑:

    pixelBuffer = UnsafeMutablePointer<CVPixelBuffer?>.allocate(capacity: MemoryLayout<CVPixelBuffer?>.size)

如果你在使用指针后不手动释放它,就会产生内存泄漏,为了避免这种情况,请将你的代码更改为以下形式:

var pixelBuffer : CVPixelBuffer? = nil
CVPixelBufferCreate(kCFAllocatorDefault, cgimg.width, cgimg.height, kCVPixelFormatType_32BGRA, nil, &pixelBuffer)

你可能想使用 pixelBuffer.deallocate(capacity: MemoryLayout<CVPixelBuffer?>.size) 来释放 pixelBuffer 的内存。 - Rocket Garden
1
@RocketGarden 你说得对,感谢指出问题,我提供了更好的解决方案。 - Samer Murad

0
func getCVPixelBuffer(_ image: CGImage) -> CVPixelBuffer? {
    let imageWidth = Int(image.width)
    let imageHeight = Int(image.height)

    let attributes : [NSObject:AnyObject] = [
        kCVPixelBufferCGImageCompatibilityKey : true as AnyObject,
        kCVPixelBufferCGBitmapContextCompatibilityKey : true as AnyObject
    ]

    var pxbuffer: CVPixelBuffer? = nil
    CVPixelBufferCreate(kCFAllocatorDefault,
                        imageWidth,
                        imageHeight,
                        kCVPixelFormatType_32ARGB,
                        attributes as CFDictionary?,
                        &pxbuffer)

    if let _pxbuffer = pxbuffer {
        let flags = CVPixelBufferLockFlags(rawValue: 0)
        CVPixelBufferLockBaseAddress(_pxbuffer, flags)
        let pxdata = CVPixelBufferGetBaseAddress(_pxbuffer)

        let rgbColorSpace = CGColorSpaceCreateDeviceRGB();
        let context = CGContext(data: pxdata,
                                width: imageWidth,
                                height: imageHeight,
                                bitsPerComponent: 8,
                                bytesPerRow: CVPixelBufferGetBytesPerRow(_pxbuffer),
                                space: rgbColorSpace,
                                bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)

        if let _context = context {
            _context.draw(image, in: CGRect.init(x: 0, y: 0, width: imageWidth, height: imageHeight))
        }
        else {
            CVPixelBufferUnlockBaseAddress(_pxbuffer, flags);
            return nil
        }

        CVPixelBufferUnlockBaseAddress(_pxbuffer, flags);
        return _pxbuffer;
    }

    return nil
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接