Swift-技巧(八)CVPixelBuffer|Swift-技巧(八)CVPixelBuffer To CGImage

摘要
Swift 中图像的表现形式不只是 Image,还有更加底层的方式,比如 CVPixelBuffer 像素缓存形式,那么像素缓存转换为可以在应用中展示的 CGImage,就要知道有哪些处理了。
CGImage 苹果官方解释是一张 bitmap 图像或者图像 mask。它是 UIImage 类中的一个属性,并可以通过 UIImage 的初始化函数称为一个 Image 对象。
CVPixelBuffer 是核心缓存像素对象的引用,这里存储着一张图像。
【Swift-技巧(八)CVPixelBuffer|Swift-技巧(八)CVPixelBuffer To CGImage】在有些应用场景中,需要把 CVPixelBuffer 转换为 CGImage,以便用来展示。
CVPixelBuffer To CGImage
CVPixelBuffer 转换获得 CGimage 对象,可以使用 VTCreateCGImageFromCVPixelBuffer(_ pixelBuffer:, options:, imageOut:) -> OSStatus 函数处理,但不是所有的 CVPixelBuffer 对象都可以支持转换。
public static func create(pixelBuffer: CVPixelBuffer) -> CGImage? { var cgImage: CGImage? VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &cgImage) return cgImage }

在使用以上函数前,要导入框架声明 VideoToolbox,毕竟不是 UIKit 框架的函数。
import VideoToolbox

除此之外,还可以使用 Core Image 作为桥梁,间接达转换效果。这里要用到 CIImage(cvPixelBuffer:)CIContext 的对象处理。
public static func create(pixelBuffer: CVPixelBuffer, context: CIContext) -> CGImage? { let ciImage = CIImage(cvPixelBuffer: pixelBuffer) let rect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer)) return context.createCGImage(ciImage, from: rect) }

若没有 context 对象传入的话,就可以直接自己创建一个 CIContext 对象,这个只是作为绘图的画布,没有非常高深的地方。
使用这个函数也是需要导入框架 CoreImage
最后一种方式,也能达到转换的效果,就是使用 CGContext 方法,它可以使用 CVPixelBuffer 对象存储创建一个 bitmap 的 CGContext 。像素格式可以支持 32ARGB,也可以更改 bitmapInfospace 属性的变量,达到改变像素格式。这种方式更加灵活,同时也相对来说比较复杂,如果有精力,可以适当了解一下。
// 使用之前记得导入框架 import CoreGraphicspublic static func create(pixelBuffer: CVPixelBuffer) -> CGImage? {guard kCVReturnSuccess == CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly) else { return nil } defer { CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly) }if let context = CGContext(data: CVPixelBufferGetBaseAddress(pixelBuffer), width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer), space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue), let cgImage = context.makeImage() { return cgImage } else { return nil } }

代码中创建 context 对象的初始化函数中的属性,都是一张图像中必须要有的信息,若对这感兴趣,给我留言,我会详细说一下图像。
题外话 时间仓促,说的东西可能不全面,在你查看的过程中遇到什么问题,评论区给我留言,我会尽快回复

    推荐阅读