首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Swift中直接用CVPixelBuffer而不是UIImage来制作UIImage?

如何在Swift中直接用CVPixelBuffer而不是UIImage来制作UIImage?
EN

Stack Overflow用户
提问于 2019-01-24 19:36:44
回答 3查看 9.6K关注 0票数 8

我是记录过滤视频通过一个iPhone相机,有一个巨大的增加时,在CIImage转换为UIImage实时记录。生成CVPixelBuffer的缓冲区函数使用UIImage,到目前为止,这要求我进行这种转换。如果可能的话,我想要创建一个接受CIImage的缓冲区函数,这样我就可以跳过从UIImage到CIImage的转换。我认为这将使我在录制视频时的性能大大提高,因为CPU和GPU之间不会有任何联系。

这就是我现在所拥有的。在我的captureOutput函数中,我从CIImage创建一个UIImage,这是经过过滤的图像。我使用CVPixelBuffer从缓冲区函数创建一个UIImage,并将其附加到assetWriter的pixelBufferInput中:

代码语言:javascript
运行
复制
let imageUI = UIImage(ciImage: ciImage)

let filteredBuffer:CVPixelBuffer? = buffer(from: imageUI)

let success = self.assetWriterPixelBufferInput?.append(filteredBuffer!, withPresentationTime: self.currentSampleTime!)

使用UIImage的缓冲区函数:

代码语言:javascript
运行
复制
func buffer(from image: UIImage) -> CVPixelBuffer? {
    let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
    var pixelBuffer : CVPixelBuffer?
    let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)

    guard (status == kCVReturnSuccess) else {
        return nil
    }

    CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
    let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!)

    let videoRecContext = CGContext(data: pixelData,
                            width: Int(image.size.width),
                            height: Int(image.size.height),
                            bitsPerComponent: 8,
                            bytesPerRow: videoRecBytesPerRow,
                            space: (MTLCaptureView?.colorSpace)!, // It's getting the current colorspace from a MTKView
                            bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)

    videoRecContext?.translateBy(x: 0, y: image.size.height)
    videoRecContext?.scaleBy(x: 1.0, y: -1.0)

    UIGraphicsPushContext(videoRecContext!)
    image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
    UIGraphicsPopContext()
    CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))

    return pixelBuffer
}
EN

Stack Overflow用户

发布于 2019-01-24 20:50:33

为了扩展我从罗布·梅奥夫那里得到的答案,我将展示我在下面改变了什么:

在captureOutput函数中,我将代码更改为:

代码语言:javascript
运行
复制
let filteredBuffer : CVPixelBuffer? = buffer(from: ciImage)

filterContext?.render(_:ciImage, to:filteredBuffer!)

let success = self.assetWriterPixelBufferInput?.append(filteredBuffer!, withPresentationTime: self.currentSampleTime!)

注意,缓冲区函数传递一个ciImage。我格式化了我的缓冲区函数以传递CIImage,并且能够处理掉许多内部的内容:

代码语言:javascript
运行
复制
func buffer(from image: CIImage) -> CVPixelBuffer? {
    let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
    var pixelBuffer : CVPixelBuffer?
    let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.extent.width), Int(image.extent.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)

    guard (status == kCVReturnSuccess) else {
        return nil
    }

    return pixelBuffer
}
票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54354138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档