Ping Lin
Ping Lin

Reputation: 51

Swift pixelbuffer cicontext.render has a black background, how to make it transparent?

When I use func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!), I need to add a transparent image to the sampleBuffer, but I always get a black background, code is here:

let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let eagleContext = EAGLContext(api: .openGLES3)
let ciContex = CIContext.init(eaglContext: eagleContext!, options: [kCIContextWorkingColorSpace:NSNull()])
let filterdImage = CIImage(cgImage: #imageLiteral(resourceName: "att_id").cgImage!)
let colorSpace = CGColorSpaceCreateDeviceRGB()
ciContex.render(filterdImage, to: pixelBuffer!, bounds: filterdImage.extent, colorSpace: colorSpace)
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
videoWriterInput.append(sampleBuffer)

I want to know how can I get the background clear color.

Upvotes: 5

Views: 510

Answers (1)

iSpain17
iSpain17

Reputation: 3053

Note: This answer assumes you have a background over which you want to render your image with transparent parts.


I have found no way to make a CIContext drop its base black background, so the only way I managed to solve this issue is creating two layers:

  • a "base" layer (for me, it's just a CIColor.white, but it can be a background video frame for you, anything, without transparency)
  • the layer of the image

This means that the final context rendering will be as follows:

let base = CIImage(color: .white) // or some other CIImage which covers the whole frame.
let finalImage = imageWithTransparency.composited(over: base)

context.render(finalImage, 
               to: somePixelBuffer,
               bounds: finalImage.extent,
               colorSpace: someColorSpaceMatchingThePixelBuffer)

Upvotes: 0

Related Questions