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