2

Given a UIImage/NSImage or NSData instance, how do you find out programatically if a PNG is 8 bits or 24 bits? And if it has an alpha channel?

Is there any Cocoa/Cocoa Touch API that helps with this?

To avoid duplication, here is the non-programatic answer to the question, and here's a way to find out if an image is a PNG.

Community
  • 1
  • 1
hpique
  • 119,096
  • 131
  • 338
  • 476
  • https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGImage/Reference/reference.html#//apple_ref/doc/uid/TP30000956-CH1g-TPXREF183 – Desdenova Apr 18 '13 at 11:50

1 Answers1

4

As a person who programmed for a long time on a J2ME platform, I know the PNG format very well. If you have the raw data as a NSData instance, looking up the information is very easy since the PNG format is very straightforward.

See PNG Specification

The PNG file starts with a signature and then it contains a sequence of chunks. You are interested only in the first chunk, IHDR.

So, the code should be along the lines of:

  1. Skip the first 8 bytes (signature)
  2. Skip 4 bytes (IHDR chunk length)
  3. Skip 4 bytes (IHDR chunk type = "IHDR")
  4. Read IHDR

Width: 4 bytes
Height: 4 bytes
Bit depth: 1 byte
Color type: 1 byte
Compression method: 1 byte
Filter method: 1 byte
Interlace method: 1 byte

For alpha, you should also check if there is a tRNS (transparency) chunk in the file. To find a chunk, you can go with the following algorithm:

  1. Read chunk length (4 bytes)
  2. Read chunk type (4 bytes)
  3. Check chunk type whether it is the type we are looking for
  4. Skip chunk length bytes
  5. Skip 4 bytes of CRC
  6. Repeat

EDIT:

To find info about a UIImage instance, get its CGImage and use one of the CGImageGet... functions. It should be noted that All integer values in a PNG file are read in Big-endian format.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • 1
    +1 Bear in mind that a PNG can implement transparency either by having an alpha channel (you read that in the "Color type" IHDR property) OR, for some image types, by including a tRNS chunk. More info [here](http://stackoverflow.com/questions/13569887/libpng-palette-png-with-alpha-or-not/13570973#13570973) – leonbloy Apr 18 '13 at 13:17
  • Is it guaranteed that the `CGImage` will have the same properties than the original data? – hpique Apr 18 '13 at 14:06
  • @hpique That really depends on how the image is created. I know that the iOS PNG loader could not load some of the unusual PNG formats. I remember implementing my own PNG parser in one ocassion and the `CGImage` created by my implementation definitely had the correct properties :) When speaking about iOS PNG loader, alpha information should be correct, not sure about the bit depth. See also http://stackoverflow.com/questions/3251595/iphone-sdk-accessing-indexed-color-png-images for info about paletted PNG images. – Sulthan Apr 18 '13 at 14:17