iOS UIImage存储格式、内存使用和编码/解码
iOS如何存储从压缩数据(jpeg2000、png、jpg等)加载的图像 示例:iOS UIImage存储格式、内存使用和编码/解码,ios,image,png,jpeg,Ios,Image,Png,Jpeg,iOS如何存储从压缩数据(jpeg2000、png、jpg等)加载的图像 示例:[UIImage-imageWithData:pngData] 它是在内部存储实际编码的字节并按需解压缩,还是永久解压缩为原始像素或其他格式?一旦加载到内存中,UIImage就是未压缩的RGBA格式。这意味着图像在内存中采用width x height x 4字节,其中width和height是以像素为单位的图像大小 UIImage在某些情况下可能会提供一些优化,但您应该在上述方面进行规划 更新: 我突然想到,上述情
[UIImage-imageWithData:pngData]
它是在内部存储实际编码的字节并按需解压缩,还是永久解压缩为原始像素或其他格式?一旦加载到内存中,
UIImage
就是未压缩的RGBA
格式。这意味着图像在内存中采用width x height x 4
字节,其中width
和height
是以像素为单位的图像大小
UIImage
在某些情况下可能会提供一些优化,但您应该在上述方面进行规划
更新:
我突然想到,上述情况可能并不总是正确的
UIImage
具有CGImage
属性。还有各种函数,如cgmagegetbitmapinfo
和cgmagegetalphainfo
以及一些其他相关函数。这些函数的返回值表示图像可以采用多种不同的格式。有各种32位格式,以及24位和16位格式。alpha可以是第一个、最后一个,也可以根本不在那里。字节顺序可以是大端或小端。一旦加载到内存中,UIImage
就是未压缩的RGBA
格式。这意味着图像在内存中采用width x height x 4
字节,其中width
和height
是以像素为单位的图像大小
UIImage
在某些情况下可能会提供一些优化,但您应该在上述方面进行规划
更新:
我突然想到,上述情况可能并不总是正确的
UIImage
具有CGImage
属性。还有各种函数,如cgmagegetbitmapinfo
和cgmagegetalphainfo
以及一些其他相关函数。这些函数的返回值表示图像可以采用多种不同的格式。有各种32位格式,以及24位和16位格式。alpha可以是第一个、最后一个,也可以根本不在那里。字节顺序可以是大的,也可以是小的。我在iPad2上创建了一个测试应用程序,使用以下三种方法加载了200 384x384像素的jpeg2000图像文件(117964800字节的原始像素):[UIImage imageNamed]
,[UIImage imageWithContentsOfFile://code>和[UIImage imageWithData]
。jpeg2000文件集是100个纹理,然后我将这些纹理复制到额外的100个带有“复制”后缀的文件中,以查看iOS是否执行任何重复文件检查,它确实执行了。下面有更多关于这方面的内容
试验分两步进行
只需加载图像并将其存储在数组中李>
一个单独的按钮为每个图像创建UIImageView并显示它们
结果如下:
[UIImage ImageName:]
第1步:内存只增加了所有jpeg2000文件的总和(每个文件大约50K,所以内存增加了大约5MB)。我假设复制的文件在这一点上没有被复制,并且以某种方式被iOS整合,因为如果没有重复检查的话,内存在这一点上会增加10MB
第2步:内存显著增加(约200 MB),可能是因为图像被解码为BGRA格式,准备在UIImageView中显示。看起来在这个阶段没有重复过滤,并且为每个图像分配了单独的原始内存。我不知道为什么,但这比实际的原始像素内存使用量多了大约80MB
[UIImage imageWithContentsOfFile:]
步骤1:内存使用与[UIImage imageNamed::
相同,因此在此阶段存在重复筛选
第2步:内存使用量增加到130 MB。由于某些原因,这比[UIImage ImageName::
低70 MB。这个数字非常接近200幅图像的预期原始像素内存量
[UIImage imageWithData:]
[NSData DATA WITH CONTENTS OFFILE::
首先使用
步骤1:内存使用量为15 MB。我假设这里没有重复过滤,因为这接近所有jpeg2000数据的总文件大小
第2步:内存使用量增加到139 MB。这比[UIImage imageWithContentsOfFile:
要多,但不多
总结
iOS似乎会引用使用上述三种方法加载的UIImage
的压缩数据,直到实际需要原始像素,然后对其进行解码
[UIImage ImageName::][/code>从未解除分配内存,因为我的所有图像视图都引用了这些图像。如果我交错加载并允许运行循环执行,它将释放未引用图像的内存。一个优点是,对同一个映像的重复调用基本上是免费的。不要将此方法用于GUI图像以外的任何对象,否则可能会耗尽内存
[UIImage imageWithContentsOfFile:][/code>的行为类似于[UIImage imageNamed:][/code>在需要原始像素之前的内存使用,在这一点上,出于某种原因,它的内存使用效率要高得多。此方法还导致在解除分配UIImage时立即释放内存。重复调用具有相同文件的[UIImage imageWithContentsOfFile:
似乎会使用缓存副本,直到所有引用该文件的UIImage
被解除分配
[UIImage imageWithData::
不进行缓存或重复检查,始终创建新图像
我测试了与PNG文件相同的集合,imageNamed和imageWithContentsOfFile的步骤1结果显示使用的内存更少(约0.5 MB),imageWithData显示了所有PNG文件的总和