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

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在某些情况下可能会提供一些优化,但您应该在上述方面进行规划 更新: 我突然想到,上述情

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

示例:
[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文件的总和