Search code examples
swiftcore-graphics

Empty CGContext


In Objective-C I was able to use CGBitmapContextCreate to create an empty context. I am trying to to the same in Swift 3, but for some reason it is nil. What am I missing?

let inImage: UIImage = ...
let width = Int(inImage.size.width)
let height = Int(inImage.size.height)

let bitmapBytesPerRow = width * 4
let bitmapByteCount = bitmapBytesPerRow * height

let pixelData = UnsafeMutablePointer<UInt8>.allocate(capacity: bitmapByteCount)

let context = CGContext(data: pixelData,
                                width: width,
                                height: height,
                                bitsPerComponent: 8,
                                bytesPerRow: bitmapBytesPerRow,
                                space: CGColorSpaceCreateDeviceRGB(),
                                bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue)

Solution

  • I'm not sure what the code in the liked article would do, but two things are different with your Swift code.

    • bytesPerRow: width // width * 4 (== bitmapBytesPerRow)
    • space : NULL // CGColorSpaceCreateDeviceRGB()

    The documentation of CGBitmapContextCreate does not say anything about supplying NULL for colorspace, but the header doc says The number of components for each pixel is specified by space, so, at least, CGColorSpaceCreateDeviceRGB() is not appropriate for alphaOnly (which should have only 1 component per pixel).

    As far as I tested, this code returns non-nil CGContext:

        let bitmapBytesPerRow = width //<-
        let bitmapByteCount = bitmapBytesPerRow * height
    
        let pixelData = UnsafeMutablePointer<UInt8>.allocate(capacity: bitmapByteCount)
    
        let context = CGContext(data: pixelData,
                                width: width,
                                height: height,
                                bitsPerComponent: 8,
                                bytesPerRow: bitmapBytesPerRow,
                                space: CGColorSpaceCreateDeviceGray(), //<-
                                bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue)
    

    But, not sure if this works for your purpose or not.