Search code examples
objective-cswiftcore-graphicsswift4

Translate CGBitmapContextCreate from Objective-C to Swift


unsigned char pixelData[4] = { 0, 0, 0, 0 };
CGContextRef context = CGBitmapContextCreate(pixelData,
    1,
    1,
    bitsPerComponent,
    bytesPerRow,
    colorSpace,
    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

I want to translate unsigned char pixelData[4] = { 0, 0, 0, 0 }; to Swift. It seems I have to use UnsafeMutableRawPointer. But I do not know how.


Solution

  • You can use a native Swift array and then call its withUnsafeMutableBytes method to get an UnsafeMutableRawBufferPointer to the array's storage. The baseAddress property then gets you the address of the buffer as an UnsafeMutableRawPointer?.

    Here's an example:

    import CoreGraphics
    
    var pixelData: [UInt8] = [0, 0, 0, 0]
    pixelData.withUnsafeMutableBytes { pointer in
        guard let colorSpace = CGColorSpace(name: CGColorSpace.displayP3),
            let context = CGContext(data: pointer.baseAddress,
                                    width: 1,
                                    height: 1,
                                    bitsPerComponent: 8,
                                    bytesPerRow: 4,
                                    space: colorSpace,
                                    bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
        else {
            return
        }
        // Draw a white background
        context.setFillColor(CGColor.white)
        context.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
    }
    
    print(pixelData) // prints [255, 255, 255, 255]
    

    Note that the pointer is only valid inside the closure you pass to withUnsafeMutableBytes. Since the graphics context assumes this pointer is valid for the duration of the context's lifetime, returning the context from the closure and accessing it from the outside would be undefined behavior.

    As you can see, however, the contents of the pixelData array have been changed when withUnsafeMutableBytes returns.