BlackDog Foundry Bookmark This page

I was adding some images to the asset catalog in Xcode today, and noticed that it was behaving really weirdly in that some images would render at the correct size, and others would be blown-up and look crazy.

For example, all of the images shown below are 16×16, but one of them renders in Xcode’s asset catalog as:

Correctly scaled

whereas the other looks like:

Scaled too large

Try as I might, I could not figure out why the second one was zoomed in and looking horrible. I found a utility called pngcheck and it produced the following output for the two files:

	OK: image1.png (16x16, 32-bit RGB+alpha, non-interlaced, 53.4%).
	OK: image2.png (16x16, 32-bit RGB+alpha, non-interlaced, 45.6%).

As you can see, they look exactly the same. Digging deeper, I found a -v flag for pngcheck which, for the offending PNG file, displayed:

File: image2.png (557 bytes)
  chunk IHDR at offset 0x0000c, length 13
    16 x 16 image, 32-bit RGB+alpha, non-interlaced
  chunk sBIT at offset 0x00025, length 4
    red = 8 = 0x08, green = 8 = 0x08, blue = 8 = 0x08, alpha = 8 = 0x08
  chunk pHYs at offset 0x00035, length 9: 1090x1090 pixels/meter (28 dpi)
  chunk tEXt at offset 0x0004a, length 25, keyword: Software
  chunk IDAT at offset 0x0006f, length 426
    zlib: deflated, 2K window, default compression
  chunk IEND at offset 0x00225, length 0
No errors detected in copy1.png (6 chunks, 45.6% compression).

When I compared the results of this to the one that works, the only significant difference was that the correctly-sized image had a pHYs chunk with 69 dpi (as opposed to the 28 dpi for the broken image).

It looks like Xcode is using the PNG DPI setting to control the size at which the image renders in the asset catalog. It seems to be rendering the image relative to 72dpi, which is why my 69dpi image looks sensible but my 28dpi image is scaled up. I am not sure why this is… everything I read suggests that DPI is not relevant in a non-print world.

Anyway, using pngcrush I removed the pHYs chunk so that the PNG no longer contains the DPI value by using the following command:

pngcrush -rem pHYs image1.png fixed.png

After this, the image looks like:

No DPI specified

It is a bit of a hassle that pngcrush has to create a new file that you then need to rename back to the original one, but with a bit of scripting magic, you can fix a whole directory’s worth of PNGs by using (all one line):

for file in *.png ; do pngcrush -rem pHYs "$file" "${file%.png}-fixed.png" && mv "${file%.png}-fixed.png" "$file" ; done

If anyone knows why the DPI is important for Xcode, I would love to know. Please comment, email or tweet. Thanks.

Leave a Comment »


Copyright © 2012 BlackDog Foundry