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

标签 ios image png jpeg

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

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

最佳答案

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

测试分两步完成

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

  • 结果如下:

    [UIImage imageNamed:]

    第一步:内存仅增加了所有 jpeg2000 文件的总和(每个文件约 50K,因此内存增加了约 5 MB)。我假设在这一点上重复文件没有被复制,并且以某种方式被 iOS 合并,因为如果没有重复检查,此时内存会增加 10MB。

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

    [UIImage imageWithContentsOfFile:]

    第一步:内存使用与 [UIImage imageNamed:] 相同,因此在此阶段存在重复过滤。

    第 2 步:内存使用量高达 130 MB。出于某种原因,这比 [UIImage imageNamed:] 低 70 MB .这个数字更接近 200 张图像的预期原始像素内存量。

    [UIImage imageWithData:]
    [NSData dataWithContentsOfFile:]首先使用。

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

    第 2 步:内存使用量上升到 139 MB。这比[UIImage imageWithContentsOfFile:] ,但不是很多。

    概括

    iOS 似乎引用了 UIImage 的压缩数据使用上述三种方法加载,直到真正需要原始像素,此时才对其进行解码。
    [UIImage imageNamed:]由于我所有的 ImageView 都引用了图像,因此从未释放过内存。如果我交错加载并允许运行循环执行,它将释放非引用图像的内存。优点之一是重复[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 步结果是相同的。

    关于iOS UIImage 存储格式、内存使用和编码/解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20588338/

    相关文章:

    iphone - 单击上一个按钮后如何在单选按钮上保持选择

    ios - 使用深色主题时 UITextField 占位符发生变化

    android - Android 中的低质量图像附件

    javascript - 如何获得使用css操作的图像高度

    c# - 如何将PNG图像转换为灰度而不丢失透明度C#

    linux - 将 .tex 文件转换为 PNG

    iPhone SDK : accessing indexed color PNG images

    ios - 在IOS中使用NSSortDescriptor对数组(NSString + Number)进行排序?

    ios - 在 iOS App 中访问单例

    android - 如何从 OpenCV 返回图像并在 Android Java 代码中显示它?