CGImage To CVPixelBuffer
这里使用 CGContext 对象中的函数将 CGImage 转换为 CVPixelBuffer。需要提前导入 CoreGraphics 框架。
import CoreGraphics
然后将转换函数放在 CGImage 扩展中,就可以直接访问 CGImage 对象的 width、height,甚至可以通过 self 访问到自身。
extension CGImage {
// 转换函数
…
}
实现方法
接下来按照需求由少到多的情况来处理 CGImage 到 CVPixelBuffer 。首先就是直接获取到一个 ARGB 的像素缓存对象。
public func pixelBuffer() -> CVPixelBuffer? {
return pixelBuffer(width: width, height: height, orientation: .up)
}
函数中的 width 和 height 可以直接访问到,orientation 是图像的方向,这里默认是 .up(竖直)。
那么可以调整图片的 width 和 height 转换成一个 ARGB 的像素缓存对象。
public func pixelBuffer(width: Int, height: Int,
orientation: CGImagePropertyOrientation) -> CVPixelBuffer? {
return pixelBuffer(width: width, height: height,
pixelFormatType: kCVPixelFormatType_32ARGB,
colorSpace: CGColorSpaceCreateDeviceRGB(),
alphaInfo: .noneSkipFirst,
orientation: orientation)
}
函数中多了一些参数,pixelFormatType 是像素格式类型,这里设置的就是 ARGB 格式,colorSpace 是颜色空间参数,alphaInfo 是 alpha 在内存中的位置,这几个参数如果不确定,就直接设置成这样。
这个函数可以设置这么多参数,从另外一个角度说,这个函数就是最终的实现,上面的几个函数都是对这个函数的封装处理。
这个函数的处理逻辑就是创建并配置 CGContext 对象,然后调用它的 draw 函数获取到 CBPixelBuffer 对象。如果对这些参数的意思,如何配置,还能做什么样的扩展感兴趣,给我留言。
public func pixelBuffer(width: Int, height: Int,
pixelFormatType: OSType,
colorSpace: CGColorSpace,
alphaInfo: CGImageAlphaInfo,
orientation: CGImagePropertyOrientation) -> CVPixelBuffer? {
assert(orientation == .up)
var maybePixelBuffer: CVPixelBuffer?
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]
let status = CVPixelBufferCreate(kCFAllocatorDefault,
width,
height,
pixelFormatType,
attrs as CFDictionary,
&maybePixelBuffer)
guard status == kCVReturnSuccess, let pixelBuffer = maybePixelBuffer else {
return nil
}
let flags = CVPixelBufferLockFlags(rawValue: 0)
guard kCVReturnSuccess == CVPixelBufferLockBaseAddress(pixelBuffer, flags) else {
return nil
}
defer { CVPixelBufferUnlockBaseAddress(pixelBuffer, flags) }
guard let context = CGContext(data: CVPixelBufferGetBaseAddress(pixelBuffer),
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
space: colorSpace,
bitmapInfo: alphaInfo.rawValue)
else {
return nil
}
context.draw(self, in: CGRect(x: 0, y: 0, width: width, height: height))
return pixelBuffer
}
亚马逊测评 www.yisuping.cn