13

I am in the process of updating Hungry Helga (iPhone and iPad versions) for iOS 6, and all of the PNG files in my new app bundle archives are between 20 and 40 percent larger than they were in my past releases. Of course, this is putting me over the 3G download limit of 50 MB so I'd really like to figure out what's going on.

I am currently using version 4.5 of Xcode on OSX 10.7.5. If I recall correctly the previous version was built with Xcode 4.2. I tried turning on and off PNG compression in the build settings but that had no effect on the image sizes in the bundle.

To give a concrete example, my largest PNG image is 1.9 MB as a source asset. It is 2.1 MB in the old app bundle, and 2.5 MB in the new app bundle.

Did Apple change the way the PNG compressor works or is there maybe a setting that I'm missing or something?

David H
  • 40,852
  • 12
  • 92
  • 138
Merax
  • 131
  • 1
  • 4

3 Answers3

21

I do not work for Apple nor do I have any inside information - however, I did poke around and have some theories. If you use terminal you can cd into the Xcode.app and find pngcrush there:

$ find . -name pngcrush ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush

If you then run:

./pngcrush -?

you find some interesting tidbits:

| It was compiled with LLVM 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-420.0.12) and modified by Apple as indicated in the sources.

and

-iphone (optimize for iPhone OS)

Since I too saw that some large pngs where also much larger in the bundle than the original (which I had previously crushed myself!), I wanted to see how Xcode uses pngcrush. I used an old UNIX trick:

  • move pngcrush to xpngcrush
  • create a new executable shell file that calls pngcrush with the same argument list
  • log the arguments into a text file in /tmp

What I found was that Apple calls pngcrush as:

pngcrush -q -iphone oldFile newFile

One can infer from this that this Apple specific feature of pngrush was designed specifically to tailor the image for iOS. I say tailor, not crush.

Does Apple really care if your png is the smallest possible file, to save the greatest amount of space? I'd argue, not really - the devices have fairly large file storage space. Do they really care if your app downloads really fast? Again, I'd argue not really, since the user is going to assume the time is related to the size of the app, and that that is under the control of the developers.

However, what the user is going to hold Apple accountable for is the launch speed. From the first tap to when the app starts doing something - people will believe that is all the speed of the device (which we developers know is not strictly true). With the new iPad3, some of the launch images are now really big, so what can be done to make loading them as fast as possible?

I don't know the answer to that question, but I can imagine that Apple decompresses the original image, then re-compresses it with settings that make loading it in the device as fast as possible.

PS:

1) I just disabled the crush option, and observed Xcode 4.5 copying my png files without modification.

2) To get your app size down, have you tried using JPEGs with a high quality setting - even 1? Such images will look very good and be much much smaller. Virtually all images in my app are JPEGs. You can experiment with Preview to do the conversions.

EDIT: it occurred to me there may be an elegant solution to this. That is, for really important images - ones that you want to appear as fast as possible - then use pngcrush with the '-iphone' flag. For others, use more standard pngcrush options.

One way to do this is to create a new image directory, and write a shell file that pre-processes every png with a real crusher or tje '-iphone' flag, putting the output in the original image folder (where Xcode can get them). Then turn off the automatic 'Crush PNG Files' option.

EDIT2: I entered a bug at bugreporter.apple.com and posted on the Xcode listserv - if you have an interest in this bookmark the question and come back when its updated.

EDIT3: someone gave me a link that explains in more detail the how and why of Apple's '-iphone' option ImageOptim

EDIT4: Apple responded to my bug report, confirming that they modify the images for easier processing by iOS, which may make them larger, by intent.

David H
  • 40,852
  • 12
  • 92
  • 138
  • Thanks for the detailed info but I think you misunderstood my question slightly (and changed the title to the wrong question). I know why PNG images change size between my source assets and the app bundle. My problem is that they have gotten larger (in the bundle) between Xcode versions. Using the info you gave me above, I compressed my example file with pngcrush and it came out to be 2.1 MB. So the two questions I need to investigate are where is this 2.5 MB file coming from and why doesn't "compress PNG" in the Xcode options seem to have any effect? – Merax Oct 02 '12 at 03:28
  • Would you mind posting the shell script that you replaced pngcrush with? I would like to see if my Xcode sends the same command line params that you saw. – Merax Oct 02 '12 at 03:56
  • Move old pngcrush to xpngcrush. Put this in pngcrush, then chmod +x pngcrush: #! /bin/ksh echo PNGCRUSH $@ >> /tmp/PNG.txt xpngcrush $@ – David H Oct 02 '12 at 10:40
  • I no longer see a *crush* option in Xcode's (7.x) Build Settings. – Chris Prince Dec 31 '15 at 22:51
1

Xcode 5 now got changes in image compressions. the best and compressed way is to use asset catalogs.

If even using Xcode 5 and asset catalogs doesn't result well for your app, check the other relative post PNG optimization issue using pngcrush tool for more answers could be helpful

Community
  • 1
  • 1
RamaKrishna Chunduri
  • 1,100
  • 1
  • 11
  • 15
0

Using David H's script, I found that Xcode is also passing the command line parameter "-f 0" to pngcrush. The man page indicates that the "-f 0" will disable any IDAT filtering before compression which can result in a larger PNG file. Testing on my 1.9 MB example file from above confirms:

pngcrush -iphone in.png out.png gives the 2.1 MB result that I am looking for

pngcrush -iphone -f 0 in.png out.png yields the undesired 2.5 MB result

Now the questions are: Why did Apple change this? Will it break image loading in some way if I work around it? If not, is there a setting for this in Xcode or will I always have to use a script to filter out the "-f 0" argument?

Merax
  • 131
  • 1
  • 4
  • Accepted. But the compression can differ for web-site deployment and app deployments. because app has additional capabilities of h/w utilization the images are been stored with more size and quality that fit quality retina displays. So let apple do the things great for them and also do things great for us too. Believe on Great+Great=Excellent. The other relative question http://stackoverflow.com/questions/7388324/png-optimization-issue-using-pngcrush-tool/23361487 has some positive answers too. – RamaKrishna Chunduri Apr 29 '14 at 10:13