0
votes

We have code that creates a CGImage from a PNG data provider, and then draws it on a CGBitmapContext. Most PNGs work fine, but some PNG formats are not supported (see here), so we get a NULL context. This is how we create it:

CGContextRef imageContext = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(image), 0, CGImageGetColorSpace(image), CGImageGetBitmapInfo(image));

Now, while this way doesn't work in Core Graphics, making a UIImage with the same PNG works. And we did confirm manually that the given PNG format is indeed not supported (24 bpp, 8 bpc, RGB only (no alpha channel)). Furthermore, passing a CGBitmapInfo of kCGImageAlphaPremultipliedFirst works!

So, it seems that there is a way to make stray PNGs render anyway, and UIImage implements this. But we really can't use UIImage here (we want to pre-render the bitmap on a background thread), hence the question - what is a good heuristic to render all PNGs in Core Graphics? Alternatively, what other drawing techniques can we use to achieve the same effect (but without using Core Graphics)?

1

1 Answers

2
votes

First: UIImage is thread safe, nowadays. From the docs:

It also means that image objects are themselves safe to use from any thread.

Second: Your problem is only in the restricted amount of available CGBitmapContext pixel formats.

If you always use 32bpp, RGB with premultiplied alpha everything should work. Of course you would not get the PNG's original pixel format (like color palettes, B&W or whatever) but that usually does not matter since drawing the image on screen is done in RGB.