摘要
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 對象的初始化函數中的屬性,都是一張圖像中必須要有的信息,若對這感興趣,給我留言,我會詳細說一下圖像。
題外話
時間倉促,說的東西可能不全面,在你查看的過程中遇到什么問題,評論區給我留言,我會盡快回復
