Tuesday, November 24, 2009
Getting a better picture in the emulator
Wednesday, October 28, 2009
Viewing PNG files inside .ipa files
As many now know, and iPhone app consists of a zip file renamed with a the ‘ipa’ extension. On Macs all iPhone apps are downloaded to the users Music/iTuenes/iTunes Media/Mobile Applications folder.
To open the file, go to terminal and cd to that directory.
> cd “Music/iTunes/iTunes Media/Mobile Applications”
> mkdir ~/tmp
> cp [some iphone app].ipa ~/tmp/tmp.zip
> cd ~/tmp
> unzip tmp.zip
> cd Payload/[name of app].app
> cp *.png ~/tmp
> cp *.jpg ~/tmp
... and so on.
If you try to open the PNG files you will find that they are not normal PNG files, but rather “iPhone optimized” versions.
A good explanation can be found here:
http://modmyi.com/wiki/index.php/Iphone_PNG_images
and here:
http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html
A quick check for each of the PNG files can be done using the ‘strings’ command.
> strings [someImage].png
If this then returns with a line starting with ‘CgBI’ you know this has been optimized. A normal PNG image should always start with ‘IHDR’
Also you can check an image using the ‘file’ command:
> file testImage.png
testImage.png: PNG image data, 805314566 x 396263525, 0-bit grayscale,
To fix these images you can use the tool provided here (source code only):
http://www.cyberhq.nl/2007/07/05/iphone-png-fixer-upper.html
To compile this project you will also need to install libpng
http://ethan.tira-thompson.org/Mac_OS_X_Ports.html
Once installed copy over the png.h file from /usr/local/include to some place in your home folder. Then open the iPhonePNG project and fix the path to png.h and build.
Then copy the binary found in the build/Release folder to a location in your path, say ~/bin
(or add it to your path with > export PATH = $PATH:~/bin )
A simpler approach is to use the download from http://www.newsfirerss.com/blog/?p=176
Both source code and a binary are provided.
But an even more elegant approach is provided by atPurpose, a Canadian developer. See
This app enables viewing the PNG resources directly, without having to convert them.
I haven’t tried the paid-for app as yet as it requires OS 10.6 but it looks very slick. At the bottom of the page there are 2 QL plug-ins and are free to download. They can be just placed into the /Library/QuickLook folder and should work immediately (check this).
Testing iPhonePNG
Usage for this app is simple adding the name of the PNG file to it and it will then append “-Decoded” into the name when completed. IF the image is not optimized it will give the following error:
ZLib error! -3
libpng error: Extra compressed data
[read_png_file] Error during read_image
However, the output file will be created anyway and will only contain garbled data.
Once the image has been decoded you can verify this with the ‘file’ command:
> file testImage-Decoded.png
testImage-Decoded.png: PNG image data, 50 x 33, 8-bit/color RGBA, non-interlaced
You can use the Quick Look plugin directly from the command line also if you so choose.
> qlmanage -p image.png >& /dev/null
For more info on qlmanage see:
http://www.macworld.com/article/131923/2008/02/qlterminal.html
This means that you could run a shell script to check each PNG image for "0-bit" using the file command and then if found call iPhonePNG to convert them.
Here is a small Perl script that with convert all the images in the current directory or a single image if it is specified as a parameter:
#!/usr/bin/perl -w
my $file = shift;
my @files = `ls -1 | grep png`;
my $iphonepng = "~/bin/iPhonePNG";
my $pattern = "0-bit";
if($file ne '') {
&fixPng($file);
} else {
# convert all files that are optimized.
foreach my $imageFile (@files) {
&fixPng($imageFile);
}
}
sub fixPng
{
my $thisFile = shift;
my $file_check = `file $thisFile`;
if($file_check =~ m/$pattern/) {
chomp($thisFile);
print "Convert: $iphonepng $thisFile\n";
`$iphonepng $thisFile`;
# move the decoded file to the original file.
my $decodedFile = $thisFile;
$decodedFile =~ s/.png/-Decoded.png/;
`rm $thisFile`;
`mv $decodedFile $thisFile`;
}
}
Place this in a file 'convert.pl' and then
> chmod +x convert.pl
> ./convert.pl [optional image file]
This will have now converted either a single image passed as a parameter, or all the images in the current directory.