iOS UIImage存储格式,内存使用和编码/解码

jjx*_*tra 8 png jpeg image ios

iOS如何存储从压缩数据(jpeg2000,png,jpg等)加载的图像

例: [UIImage imageWithData:pngData]

它是在内部存储实际编码的字节并按需解压缩,还是永久解压缩为原始像素或其他格式?

jjx*_*tra 12

我创建在iPad 2的测试应用程序,加载200个384x384使用以下三种方法像素JPEG2000图像文件(117964800个字节值得原始像素的): [UIImage imageNamed],[UIImage imageWithContentsOfFile:][UIImage imageWithData].jpeg2000文件集是100个纹理,然后我将其复制到一个带有"copy"后缀的额外100个文件中,以查看iOS是否进行了任何重复的文件检查.更多关于下面的内容.

测试分两步完成

  1. 只需加载图像并将其存储在一个数组中.
  2. 单独的按钮为每个图像创建UIImageViews并显示它们.

结果如下:

[UIImage imageNamed:]

步骤1:内存仅增加大约所有jpeg2000文件的总和(每个大约50K,因此内存增加了大约5 MB).我假设此时重复文件没有重复,并且以某种方式由iOS进行整合,因为如果没有重复检查,此时内存将增加10MB.

第2步:内存显着增加(大约200 MB),大概是因为图像被解码为BGRA格式,准备在UIImageView中显示.看起来在这个阶段没有重复的过滤,并且为每个图像分配了单独的原始内存.我不确定为什么,但这比实际的原始像素内存使用量大约多80 MB.

[UIImage imageWithContentsOfFile:]

步骤1:内存使用情况与此相同[UIImage imageNamed:],因此在此阶段存在重复过滤.

第2步:内存使用量增加到130 MB.由于某种原因,它比70 MB低[UIImage imageNamed:].此数字更接近200张图像的预期原始像素存储量.

[UIImage imageWithData:]

[NSData dataWithContentsOfFile:] 先用了.

第1步:内存使用量为15 MB.我假设这里没有重复过滤,因为它接近所有jpeg2000数据的总文件大小.

第2步:内存使用量增加到139 MB.这不仅仅是[UIImage imageWithContentsOfFile:],但不是很多.

摘要

iOS似乎UIImage使用上述三种方法引用加载的压缩数据,直到实际需要原始像素,此时它被解码.

[UIImage imageNamed:]从来没有释放内存,因为我的所有图像视图都引用了图像.如果我交错加载并允许运行循环执行,它将释放未引用的图像的内存.一个优点是[UIImage imageNamed:]对同一图像的重复调用基本上是免费的.不要将此方法用于GUI图像以外的任何其他方法,否则可能会耗尽内存.

[UIImage imageWithContentsOfFile:][UIImage imageNamed:]在需要原始像素之前,行为类似于内存使用,此时由于某种原因,它在内存使用方面更有效.当解除分配UIImage时,此方法还会立即释放内存.[UIImage imageWithContentsOfFile:]对同一文件的重复调用似乎使用缓存副本,直到所有UIImage引用该文件的文件都被释放.

[UIImage imageWithData:] 不进行缓存或重复检查,并始终创建新图像.

我测试了与PNG文件相同的集合,imageNamed和imageWithContentsOfFile的步骤1结果显示使用的内存更少(约0.5 MB),imageWithData显示压缩的所有PNG文件的总和.我的猜测是iOS只是存储对文件的引用,并且在解码时间之前不会对其执行任何其他操作.PNG的步骤2结果是相同的.