欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从ipa提取图片资源,还原PNG文件 博客分类: 软件开发 RubyIPAIOSPNGpngcrush 

程序员文章站 2024-03-24 17:11:16
...

iOS 开发过程中,在code和测试阶段结束后,你需要用xcode将程序打包成.ipa文件,然后上传到app store进行审批。在xcode将app打包成.ipa文件过程中,xcode会将文件压缩。我们知道这个打包过程简单来说就是一个压缩过程,如果你将ipa文件的名字改为.zip,然后再解压缩,你就可以看到ipa中包含的文件了。下面以我写的EZ Chapel Hill Transit 为例演示如何从ipa中提取图片。

 

从ipa提取图片资源,还原PNG文件
            
    
    博客分类: 软件开发 RubyIPAIOSPNGpngcrush 

Demo of un-zip ipa file

 

如上图所示,将ipa文件改名为.zip再解压后,可以看到一个名为EZ Chapel Hill Transit.ipa的文件夹,进入文件夹之后,可以看到一个叫Payload的文件夹,进入文件夹后,可以看到一个叫EZ Chapel Hill Transit.app的文件,这就是在iOS上可执行的app了,而要看app里的内容,可以右键该app,在菜单里选中Show Package Contents,进入后,就能看到app中包含的文件了。

 

从ipa提取图片资源,还原PNG文件
            
    
    博客分类: 软件开发 RubyIPAIOSPNGpngcrush 

 

Show Package Contents

但是,细细一看,就会发现app中包含的图片文件,虽然可以看到如”xxx.png”的图片,但是却不能打开浏览。

从ipa提取图片资源,还原PNG文件
            
    
    博客分类: 软件开发 RubyIPAIOSPNGpngcrush 

 

 Package Contents: cannot open image files

 

这是因为在xcode打包ipa过程中,将图片使用pngcrush程序优化过了,具体的技术细节可以参看Apple的官方技术文档(英文)和Pngcrush的官方网站(英文)。那要如何将这些被优化过的图片“反优化”成可以浏览的图片文件呢?Apple的技术文档中给了相应的方法:

In iPhone SDK 3.2 and later, the pngcrush tool supports a command line option, -revert-iphone-optimizations, that undoes the optimizations done during the Xcode build process. So, to view an optimized PNG file, you should first undo the optimization and then open it with Preview.

 

方法就是,如果你使用的iOS SDK版本在3.2之后,在terminal里执行以下命令:

 

$ /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush\ -revert-iphone-optimizations -q Local.png Local-standard.png

 

当然,你也可以写一个script或者将script封装成一个Mac OS app来简化工作。不过,Github上已经有别人写好的,你只需要下载下来使用即可。 以上便是如何从封装好的ipa文件中提取图片文件的方法。

 

批量还原png的脚本如下,把以下代码复制,保存为“ruby uncrush.rb”文件,放置你的目标文件夹中,并运行,它会创建一个"uncrushed"文件夹,还原的png将放置在这里。

 

 

files = Dir.glob("*.png")

puts "Creating directory: uncrushed"
if File.directory?("uncrushed")
  puts "Directory already exists... delete and proceed? (y/n)"
  input = gets.strip
  if input == "y"
    deletefiles = Dir.glob("uncrushed/*.png")
    deletefiles.each do |f|
      File.delete(f)
    end
    Dir.delete("uncrushed")
  else
    abort
  end
else
end
Dir.mkdir("uncrushed")
files.each do |f|
  puts "Found file: #{f}... uncrushing it because we street!"
  `/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations -q #{f} uncrushed/#{f}`
  puts "Creating new file: #{f}"
end