Swift-技巧(八)CVPixelBuffer To CGImage
摘要
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
對象的初始化函數中的屬性,都是一張影像中必須要有的資訊,若對這感興趣,給我留言,我會詳細說一下影像。
題外話
時間倉促,說的東西可能不全面,在你查看的過程中遇到什麼問題,評論區給我留言,我會儘快回復