3

I'd like to convert the UIImage to a 24-bit RGB with no inbetween 32-bit RGBA buffer.

I tried this, but it does not work (bytes is all zero) :

public func pixelsRGB() -> [UInt8]? {

    let size = self.size
    let dataSize = size.width * size.height * 3
    var pixelData = [UInt8](repeating: 0, count: Int(dataSize))
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let context = CGContext(data: &pixelData,
                            width: Int(size.width),
                            height: Int(size.height),
                            bitsPerComponent: 8,
                            bytesPerRow: 3 * Int(size.width),
                            space: colorSpace,
                            bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)
    guard let cgImage = self.cgImage else {
        return nil
    }
    context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

    return pixelData
}
Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95

1 Answers1

0

This is a bit old, but since I struggled with it too I thought it'd be good to add some of what I found.

As answered on this SO post, Quartz doesn't support a 24-bit RGB image. See supported formats here. @matt answered this question also here

I suspect it's failing to create the CGContext and returning nil for context. Then it never writes to the context and just returns the values you initialized for your byte buffer.

If you change your line:

bytesPerRow: 3 * Int(size.width),

to:

bytesPerRow: 4 * Int(size.width), //to accommodate the non-existing alpha channel

you'll get a valid context and be able to use it to draw in. Kind of a pain, but that's how I got around it.

Jonathan
  • 6,507
  • 5
  • 37
  • 47
SteveB
  • 3
  • 4