'Correct way to draw/edit a CVPixelBuffer in Swift in iOS
Is there a standard performant way to edit/draw on a CVImageBuffer/CVPixelBuffer in swift?
All the video editing demos I've found online overlay the drawing (rectangles or text) on the screen and don't directly edit the CVPixelBuffer.
UPDATE I tried using a CGContext but the saved video doesn't show the context drawing
private var adapter: AVAssetWriterInputPixelBufferAdaptor?
extension TrainViewController: CameraFeedManagerDelegate {
func didOutput(sampleBuffer: CMSampleBuffer) {
let time = CMTime(seconds: timestamp - _time, preferredTimescale: CMTimeScale(600))
let pixelBuffer: CVPixelBuffer? = CMSampleBufferGetImageBuffer(sampleBuffer)
guard let context = CGContext(data: CVPixelBufferGetBaseAddress(pixelBuffer),
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
space: colorSpace,
bitmapInfo: alphaInfo.rawValue)
else {
return nil
}
context.setFillColor(red: 1, green: 0, blue: 0, alpha: 1.0)
context.fillEllipse(in: CGRect(x: 0, y: 0, width: width, height: height))
context.flush()
adapter?.append(pixelBuffer, withPresentationTime: time)
}
}
Solution 1:[1]
You need to call CVPixelBufferLockBaseAddress(pixelBuffer, 0)
before creating the bitmap CGContext
and CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
after you have finished drawing to the context.
Without locking the pixel buffer, CVPixelBufferGetBaseAddress()
returns NULL. This causes your CGContext
to allocate new memory to draw into, which is subsequently discarded.
Also double check your colour space. It's easy to mix up your components.
e.g.
guard
CVPixelBufferLockBaseAddress(pixelBuffer) == kCVReturnSuccess,
let context = CGContext(data: CVPixelBufferGetBaseAddress(pixelBuffer),
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
space: colorSpace,
bitmapInfo: alphaInfo.rawValue)
else {
return nil
}
context.setFillColor(red: 1, green: 0, blue: 0, alpha: 1.0)
context.fillEllipse(in: CGRect(x: 0, y: 0, width: width, height: height))
CVPixelBufferUnlockBaseAddress(pixelBuffer)
adapter?.append(pixelBuffer, withPresentationTime: time)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |