본문 바로가기

카테고리 없음

[iOS] CVPixelBuffer 에 CIImage 그리기

카메라 입력등과 같이 CVPixelBuffer 에 이미지를 추가하고, 각 프레임 생성하는 예.

 

CIContext

var masterClock: CMClock!
var timestamp: CMTime!
var ciContext: CIContext?

override func viewDidLoad() {
    super.viewDidLoad()
    
        .
        .
        
    // 타임스탬프
    self.masterClock = CMClockGetHostTimeClock()
    
    // ci context
    self.ciContext = CIContext(options: [CIContextOption.outputPremultiplied: true,
                                         CIContextOption.useSoftwareRenderer: false])
         .
         .
}

 

특정 프레임별 동작을 위한 핸들러 정의

self.displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLink))
self.displayLink?.preferredFramesPerSecond = 20
self.displayLink?.add(to: RunLoop.current, forMode: RunLoop.Mode.default)
@objc func handleDisplayLink(displayLink: CADisplayLink) {
	// 실제 프레임 처리
}

 

CIImage : CVPixelBuffer에 그릴 이미지
CIImage는 각 그래픽 포맷으로부터 생성할 수 있다.

var sampleImage:CIImage?

 

필터 생성
샘플 이미지를 렌더링 하기 전에 변경 작업

// 합성 : 두 이미지를 사용하는 경우 사용하며,
// 입력 이미지의 위치를 지정하는 경우 사용 
let filterComposite: CIFilter = CIFilter( name:"CILanczosScaleTransform")
filterComposite.setValue( 1.0, forKey: kCIInputAspectRatioKey )
filterComposite.setValue( 1.0, forKey: kCIInputScaleKey )
filterComposite.setValue( sampleImage, forKey: kCIInputImageKey)

outputImage = filterComposite.outputImage

 

CVPixelBuffer 생성

var outPixelBuffer: CVPixelBuffer?
let status = CVPixelBufferCreate( kCFAllocatorDefault,
                                  Int(outImage.extent.size.width),
                                  Int(outImage.extent.size.height),
                                  kCVPixelFormatType_32BGRA, // kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
                                  nil,
                                  &outPixelBuffer);
if status != 0 {
    return
}

 

 

필터 적용 및 이미지 적용

// lock
CVPixelBufferLockBaseAddress( outPixelBuffer, [] )
   
// 필터의 이미지를 출력 이미지를 얻어 cvPixelBuffer에 렌더링            
self?.ciContext?.render( outputImage, 
                         to: outPixelBuffer, 
                         bounds: outputImage.extent, 
                         colorSpace: nil )

// unlock
CVPixelBufferUnlockBaseAddress( pixelBuffer, [] )