CMSampleBuffer -> CVPixelBuffer
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBuffer -> CIImage
let ciimage = CIImage(cvPixelBuffer: pixelBuffer)
CIImage -> CGImage
context 생성은 비용이 높으므로, 미리 생성해 두고 사용
let context = CIContext(options: nil)
let cgImage = context.createCGImage(ciimage, from: ciimage.extent)!
CIImage, CGImage -> UIImage
let uiImage = UIImage(CIImage: ciImage)
let uiImage = UIImage(CGImage: cgImage)
UIImage, CGImage -> CIImage
var ciImage = CIImage(image: uiImage)
var ciImage = CIImage(CGImage: cgImage)
CIImage - > CVPixelBuffer
let context = CIContext()
context.render(ciImage, to: pixelBuffer)
UIImage -> CVPixelBuffer
var pixelBuffer: CVPixelBuffer? = nil
let attributes = [
String(kCVPixelBufferCGImageCompatibilityKey): false,
String(kCVPixelBufferCGBitmapContextCompatibilityKey): false,
] as CFDictionary
// 사이즈 정보
let width = Int(uiImage.size.width)
let height = Int(uiImage.size.height)
let colorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB()
// bgra : .bytePrder32Littel
// argb : .noneSkipFirst
// gray : .none
let alphInfo: CGImageAlphaInfo = .byteOrder32Little
let pixelFormat: OSType = kCVPixelFormatType_32BGRA
// 픽셀버퍼 생성
let result = CVPixelBufferCreate( kCFAllocatorDefault,
width,
height,
pixelFormat,
attributes,
&pixelBuffer)
guard let pixelBuffer = pixelBuffer else { return nil }
let flag = CVPixelBufferLockFlags(rawValue: 0)
CVPixelBufferLockBaseAddress(pixelBuffer, flag)
defer {
CVPixelBufferUnlockBaseAddress(pixelBuffer, flag)
}
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let context = CGContext(data: pixelData,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: colorSpace,
bitmapInfo: alphaInfo.rawValue )
// bitmap 형식 기준 좌표 변경
context?.translateBy(x: 0, y: CGFlaot(height))
context?.scaleBy(x: 1, y: -1)
// 이미지 그리기
context?.draw(uiImage.cgImage!, in: CGRect(origin: .zero, size: CGSize(width: width, height: height))
CVPixelBuffer -> CMSampleBuffer
let pixelBuffer = cvPixelBuffer
var sampleBuffer: CMSampleBuffer? = nil
// 타임 정보
var timimgInfo: CMSampleTimingInfo = CMSampleTimingInfo.invalid
var videoInfo: CMVideoFormatDescription? = nil
CMVideoFormatDescriptionCreateForImageBuffer(allocator: nil,
imageBuffer: pixelBuffer!,
formatDescriptionOut: &videoInfo)
CMSampleBufferCreateForImageBuffer(allocator: kCFAllocatorDefault,
imageBuffer: pixelBuffer!,
dataReady: true,
makeDataReadyCallback: nil,
refcon: nil,
formatDescription: videoInfo!,
sampleTiming: &timimgInfo,
sampleBufferOut: &sampleBuffer)
CGImage - > Array
var array = [UInt8](repeating: 0, count: cgImage.width * cgImage.height * 4)
array.withUnsafeMutableBytes { ptr in
let context = CGContext( data: ptr.baseAddress,
width: cgImage.width,
height: cgImage.height
bitsPerComponent: cgImage.bitsPerComponent,
bytesPerRow: cgImage.bytesPerRow,
space: cgImage.colorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
let rect = CGRect( origin: .zero, size: CSize(width: cgImage.width, height: cgImage.height))
context?.draw(cgImage, in: rect)
}
Array -> CGImage
배열의 경우 width, height, bitsPerComponent, bytesPerRow, colorSpace 등 이미지에 대한
기본 정보를 별도 관리 해야함.
var cgImage = array.withUnsafeBytes { ptr in
var data = UnsafeMutableRawPointer(mutating: ptr.baseAddress)
let context = CGContext(data: data,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: colorSpace,
bitmapInfo, alphaInfo.rawValue)
return context?.makeImage()
}
'프로그래밍 > iOS,macOS' 카테고리의 다른 글
collection view 에서 load more 처리 (0) | 2021.07.20 |
---|---|
UIPanGestureRecognizer 슬라이드 다운 뷰 (0) | 2021.07.01 |
UITextView 사이즈 조정 및 글자 제한, placeholder (0) | 2021.06.30 |
UITextView 자동 높이 (0) | 2021.06.03 |
오디오유닛 레벨 계산 (0) | 2021.05.01 |
아이폰 로컬 화면 공유 : Broadcast Extension (0) | 2021.03.19 |
[Metal] 이미지렌더링~ 카메라 입력과 가우시안 블러~ (1) | 2021.02.13 |
CVPixelBuffer, CMSampleBuffer,Data, Metal Texture, vImage (0) | 2021.02.09 |
[Metal] 이미지 렌더링~ 가우시안 블러~ Kernel 쉐이더 (0) | 2021.02.07 |
[Metal] 이미지 렌더링~ 가우시안 블러 (0) | 2021.02.07 |