Swift-技巧(九)CGImage To CVPixelBuffer

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值