CMSampleBuffer轉UIImage
// CMSampleBuffer -> UIImage
func sampleBufferToImage(sampleBuffer: CMSampleBuffer) -> UIImage {
// 獲取CMSampleBuffer的核心視頻圖像緩沖的媒體數據
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! as CVPixelBuffer
// 鎖定像素緩沖區的基址
CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))
// 獲取像素緩沖區的每行字節數
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)
// 獲取像素緩沖區的每行字節數
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
// 獲取像素緩沖的寬度和高度
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
// 創建一個設備相關的RGB顏色空間
let colorSpace = CGColorSpaceCreateDeviceRGB()
// 使用示例緩沖區數據創建位圖圖形上下文
let context = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8,
bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
// 根據位圖圖形上下文中的像素數據創建一個Quartz圖像
let quartzImage:CGImage = context!.makeImage()!
// 解鎖像素緩沖區
CVPixelBufferUnlockBaseAddress(imageBuffer,CVPixelBufferLockFlags(rawValue: 0))
let image = UIImage(cgImage: quartzImage)
return image
}
UIImage轉CVPixelBuffer
// UIImage -> CVPixelBuffer
func imageToCVPixelBuffer(image:UIImage) -> CVPixelBuffer? {
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
var pixelBuffer : CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
guard (status == kCVReturnSuccess) else {
return nil
}
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(data: pixelData, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
context?.translateBy(x: 0, y: image.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
UIGraphicsPushContext(context!)
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
UIGraphicsPopContext()
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
return pixelBuffer
}