背景:新项目有更换引导图的需求,这次引导图UI切给我的图的大小是7M,但是切换新的引导图之后,打出来的ipa包由上一个版本的20M变成了50M。
问题分析以及初期尝试
-
分析: 对比上一个版本的引导图和新引导图打成ipa包之后的引导图大小,发现引导图都是有增大的。搜索资料发现说是苹果对于png的优化处理,下面是引导图增大的对比,至于苹果的优化机制会在后面分析。
尝试一: 使用Compress PNG File这个配置开关关闭苹果优化的文档说明,尝试之后ipa包没有明显的缩小;
尝试二: 使用ImageOptim压缩引导图,形成压缩的png文件,同时关闭Compress PNG File开关,依然是没有效果;
苹果对于图片的存储方式简析
一、Assets存储
- 1. 概述:Assets.xcassets 一般是以蓝色的Assets.xcassets的文件夹形式在工程中,以Image Set的形式管理。当一组图片放入的时候同时会生成描述文件Contents.json。且在打包后以Assets.car的形式存在,不能打开。 开发中一般在工程内导入两个到三个同内容不同像素的图片文件。
- 2. 特性:ImageAssets 也是从图片文件中读取图片数据转为 UIImage, 只不过这些图片数据都打包在 ImageAssets 中. 还有一个最大的区别就是图片缓存. 相当于有一个字典, key 是图片名, value是图片对象. 调用imageNamed:方法时候先从这个字典里取, 如果取到就直接返回, 如果取不到再去文件中创建, 然后保存到这个字典后再返回. 由于字典的key和value都是强引用, 所以一旦创建后的图片永不销毁.
- 3. 优势:性能好,节省Disk。Asset Catalogs会用一个高度优化的特殊格式来存所有图片,而不是一个一个的单独的图片资源,会更少的涉及频繁Disk I/O操作,且会按需下载适合你机型的合适分辨率的图片资源; 安全性。图片资源得到一定程度保护(Asset,car不易打开)。当一个 icon 在多个地方需要被显示的时候, 其对应的UIImage对象只会被创建一次, 而且多个地方的 icon 都将会共用一个 UIImage 对象. 减少沙盒的读取操作.
- 4. 使用场景:ImageAssets 最主要的使用场景就是 icon 类的图片, 一般 icon 类的图片大小在 3kb 到 20 kb 不等, 都是一些小文件.
二、图片存储在项目文件中
- 1. 概述:将文件直接拖入到工程目录下, 并告诉Xcode打包项目时候把这些图片文件打包进去. 这样在应用的".app"文件夹中就有这些图片.
- 2. 特性:在 Resource 的图片管理方式中, 所有的图片创建都是通过读取文件数据得到的, 读取一次文件数据就会产生一次NSData以及产生一个UIImage, 当图片创建好后销毁对应的NSData, 当UIImage的引用计数器变为0的时候自动销毁UIImage. 这样的话就可以保证图片不会长期地存在在内存中.
- 3. 优势:图片的生命周期可以得到管理无疑是 Resource 最大的优点, 当我们需要图片的时候就创建一个, 当我们不需要这个图片的时候就让他销毁. 图片不会长期的保存在内存当中, 所以不会有很多的内存浪费. 同时, 大图一般不会长期使用, 而且大图占用内存一般比小图多了好多倍, 所以在减少大图的内存占用中, Resource 做的非常好.
- 4. 使用场景:由于这种方法的特性, 所以 Resource 的方法一般用在图片数据很大, 图片一般不需要多次使用的情况. 比如说引导页背景(图片全屏, 有时候运行APP会显示, 有时候根本就用不到).
苹果优化简析
1. Compress PNG File配置的作用
- Compress PNG Files作用分析这篇文章作者从png文件格式的角度,通过对比苹果优化png图片前后的格式对比。阐述了苹果出于为了加快对图片的处理速度,将其转换为自己更方便处理的格式--CgBI格式。并且修改了存放实际的图像数据的IDAT数据块,改变了决定IDAT数据块大小的Filter方式、zlib的压缩方式。因为CgBI的IDAT是BGRA格式的,所以不管之前的IDAT是否有Alpha通道,在处理的时候,都会增加alpha通道,其次就是因为每一行数据的filter不同,apple处理的时候,默认每一行都使用相同的filter,而原始文件则可以通过更好的算法,对不同的数据行使用不同的filter,为后面的数据压缩提供更容易压缩的数据。因此苹果对于png的优化可能会导致部分png图片变大的情况。
- ipa包提交到AppStore会比本地build大一些的原因:作为提交到App Store中app里的可执行文件是被加过密的。加密的副作用是可执行文件的压缩效果没有之前的好了,因为加密会隐藏一些细节问题。因此,从App Store下载下来的.ipa文件大小要比从本地build出来的.ipa文件大。
解决方案
-
修改引导图放入方式由Assets改为直接存储在项目文件中,下图是一些方案的对比。
- 通过对比发现,将png图片直接导入工程,苹果虽然依然会对其进行优化。如果想禁用苹果对png图片的优化,也可以将png图片的类型修改为data类型,不影响展示效果,并且打成ipa包之后图片大小不会改变。