Swift-技巧(八)CVPixelBuffer To CGImage

2021年11月26日 阅读数:1
这篇文章主要向大家介绍Swift-技巧(八)CVPixelBuffer To CGImage,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

摘要swift

Swift 中图像的表现形式不仅是 Image,还有更加底层的方式,好比 CVPixelBuffer 像素缓存形式,那么像素缓存转换为能够在应用中展现的 CGImage,就要知道有哪些处理了。缓存

CGImage 苹果官方解释是一张 bitmap 图像或者图像 mask。它是 UIImage 类中的一个属性,并能够经过 UIImage 的初始化函数称为一个 Image 对象。框架

CVPixelBuffer 是核心缓存像素对象的引用,这里存储着一张图像。ide

在有些应用场景中,须要把 CVPixelBuffer 转换为 CGImage,以便用来展现。函数

CVPixelBuffer To CGImage

CVPixelBuffer 转换得到 CGimage 对象,可使用 VTCreateCGImageFromCVPixelBuffer(_ pixelBuffer:, options:, imageOut:) -> OSStatus 函数处理,但不是全部的 CVPixelBuffer 对象均可以支持转换。spa

public static func create(pixelBuffer: CVPixelBuffer) -> CGImage? {
  var cgImage: CGImage?
  VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &cgImage)
  return cgImage
}

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

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 对象,这个只是做为绘图的画布,没有很是高深的地方。ip

使用这个函数也是须要导入框架 CoreImageci

最后一种方式,也能达到转换的效果,就是使用 CGContext 方法,它可使用 CVPixelBuffer 对象存储建立一个 bitmap 的 CGContext 。像素格式能够支持 32ARGB,也能够更改 bitmapInfospace 属性的变量,达到改变像素格式。这种方式更加灵活,同时也相对来讲比较复杂,若是有精力,能够适当了解一下。

// 使用以前记得导入框架
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 对象的初始化函数中的属性,都是一张图像中必需要有的信息,若对这感兴趣,给我留言,我会详细说一下图像。

题外话

时间仓促,说的东西可能不全面,在你查看的过程当中遇到什么问题,评论区给我留言,我会尽快回复