计算机系统应用教程网站

网站首页 > 技术文章 正文

Swift-技巧(八)CVPixelBuffer To CGImage

btikc 2024-09-04 03:19:54 技术文章 10 ℃ 0 评论


摘要

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

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

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

在有些应用场景中,需要把 CVPixelBuffer 转换为 CGImage,以便用来展示。

CVPixelBufferTo 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 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 对象的初始化函数中的属性,都是一张图像中必须要有的信息,若对这感兴趣,给我留言,我会详细说一下图像。

题外话

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



Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表