Skip to content

Instantly share code, notes, and snippets.

@haikieu
Forked from omarojo/imageToPixelBuffer.swift
Created May 31, 2020 08:20
Show Gist options
  • Save haikieu/9c28f57e6a1f67884bf2115f9a4fd956 to your computer and use it in GitHub Desktop.
Save haikieu/9c28f57e6a1f67884bf2115f9a4fd956 to your computer and use it in GitHub Desktop.
Image To CVPixelBuffer in Swift
var thePixelBuffer : CVPixelBuffer?
let testImage : UIImage = UIImage.init(named: "twdEnds.png")!
self.thePixelBuffer = self.pixelBufferFromImage(image: testImage)
func pixelBufferFromImage(image: UIImage) -> CVPixelBuffer {
let ciimage = CIImage(image: image)
//let cgimage = convertCIImageToCGImage(inputImage: ciimage!)
let tmpcontext = CIContext(options: nil)
let cgimage = tmpcontext.createCGImage(ciimage!, from: ciimage!.extent)
let cfnumPointer = UnsafeMutablePointer<UnsafeRawPointer>.allocate(capacity: 1)
let cfnum = CFNumberCreate(kCFAllocatorDefault, .intType, cfnumPointer)
let keys: [CFString] = [kCVPixelBufferCGImageCompatibilityKey, kCVPixelBufferCGBitmapContextCompatibilityKey, kCVPixelBufferBytesPerRowAlignmentKey]
let values: [CFTypeRef] = [kCFBooleanTrue, kCFBooleanTrue, cfnum!]
let keysPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
let valuesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
keysPointer.initialize(to: keys)
valuesPointer.initialize(to: values)
let options = CFDictionaryCreate(kCFAllocatorDefault, keysPointer, valuesPointer, keys.count, nil, nil)
let width = cgimage!.width
let height = cgimage!.height
var pxbuffer: CVPixelBuffer?
// if pxbuffer = nil, you will get status = -6661
var status = CVPixelBufferCreate(kCFAllocatorDefault, width, height,
kCVPixelFormatType_32BGRA, options, &pxbuffer)
status = CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
let bufferAddress = CVPixelBufferGetBaseAddress(pxbuffer!);
let rgbColorSpace = CGColorSpaceCreateDeviceRGB();
let bytesperrow = CVPixelBufferGetBytesPerRow(pxbuffer!)
let context = CGContext(data: bufferAddress,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesperrow,
space: rgbColorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue);
context?.concatenate(CGAffineTransform(rotationAngle: 0))
context?.concatenate(__CGAffineTransformMake( 1, 0, 0, -1, 0, CGFloat(height) )) //Flip Vertical
// context?.concatenate(__CGAffineTransformMake( -1.0, 0.0, 0.0, 1.0, CGFloat(width), 0.0)) //Flip Horizontal
context?.draw(cgimage!, in: CGRect(x:0, y:0, width:CGFloat(width), height:CGFloat(height)));
status = CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
return pxbuffer!;
}
@haikieu
Copy link
Author

haikieu commented Jun 5, 2020

Note:
if you are using this buffer to do some Metal work then add kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue to attrs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment