摘要
Swift 中图像的表现形式不只是 Image,还有更加底层的方式,比如
CVPixelBuffer
像素缓存形式,那么像素缓存转换为可以在应用中展示的 CGImage,就要知道有哪些处理了。
CGImage 苹果官方解释是一张 bitmap 图像或者图像 mask。它是 UIImage 类中的一个属性,并可以通过 UIImage
的初始化函数称为一个 Image 对象。
CVPixelBuffer 是核心缓存像素对象的引用,这里存储着一张图像。
在有些应用场景中,需要把 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,也可以更改 bitmapInfo
和 space
属性的变量,达到改变像素格式。这种方式更加灵活,同时也相对来说比较复杂,如果有精力,可以适当了解一下。
// 使用之前记得导入框架
import CoreGraphics
public 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
对象的初始化函数中的属性,都是一张图像中必须要有的信息,若对这感兴趣,给我留言,我会详细说一下图像。
题外话
时间仓促,说的东西可能不全面,在你查看的过程中遇到什么问题,评论区给我留言,我会尽快回复