Reputation: 737
I use this simple code to load image from Temp directory
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()
}
}
Every new image need a lot of memory to be visualized. In this project I need to load 20-30 images and therefore I should reduce the memory needed for each image which is now about 23mb per image.
Is it possible to load the image directly from its path without adding it to memory? Any suggestions? Many thanks!
Upvotes: 3
Views: 1750
Reputation: 535
Anything that you want to display in your app should be loaded into memory, so I believe there is nothing to do on that part.
On iOS, UIImage's memory usage is relative to the image dimensions. For example, if you have 1920x1080 image, it will approximately consume about 8 megabytes in the memory (1920 * 1080 * 4 bytes).
Because as mentioned in WWDC 2018, "Memory use is related to the dimensions of the image, not the file size."
So as a solution, you can use an image that has lower dimensions, or you can downsample the image before presenting it.
Here is an example function for downsampling an image, credits to 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, 0, downsampleOptions) else {
return nil
}
// Return the downsampled image as UIImage
return UIImage(cgImage: downsampledImage)
}
Upvotes: 7