在 SwiftUI 中加载多个 UIImage 的内存问题

问题描述

我使用这个简单的代码从 Temp 目录加载图像


struct AddNewMedia: View {

      @State var filename:String

      func imageFullPath(filename:String)->UIImage {
           let pathToTemoDir = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
               return UIImage(contentsOfFile: pathToTemoDir.path)!
      }

         var body: some View {

             Image(uiImage: self.imageFullPath(filename: filename))
               .resizable()
               .scaledToFit()
     }
}

每个新图像都需要大量内存才能可视化。 在这个项目中,我需要加载 20-30 张图片,因此我应该减少每张图片所需的内存,现在每张图片大约 23mb。

是否可以直接从其路径加载图像而不将其添加到内存中?有什么建议么?非常感谢!

解决方法

您想在应用中显示的任何内容都应该加载到内存中,所以我相信这部分没有什么可做的。

在 iOS 上,UIImage 的内存使用是相对于图像尺寸的。例如,如果您有 1920x1080 的图像,它大约会消耗大约 8 兆字节的内存(1920 * 1080 * 4 字节)。

因为如 WWDC 2018 中所述,“内存使用与图像的尺寸有关,与文件大小无关。”

因此,作为解决方案,您可以使用维度较低的图像,或者您可以在呈现图像之前对图像进行下采样。

这是对图像进行下采样的示例函数,归功于 this link

func downsample(imageAt imageURL: URL,to pointSize: CGSize,scale: CGFloat = UIScreen.main.scale) -> UIImage? {

    // Create an CGImageSource that represent an image
    let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
    guard let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL,imageSourceOptions) else {
        return nil
    }
    
    // Calculate the desired dimension
    let maxDimensionInPixels = max(pointSize.width,pointSize.height) * scale
    
    // Perform downsampling
    let downsampleOptions = [
        kCGImageSourceCreateThumbnailFromImageAlways: true,kCGImageSourceShouldCacheImmediately: true,kCGImageSourceCreateThumbnailWithTransform: true,kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels
    ] as CFDictionary
    guard let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource,downsampleOptions) else {
        return nil
    }
    
    // Return the downsampled image as UIImage
    return UIImage(cgImage: downsampledImage)
}