In my app, I have an image array which holds all the images taken on my camera. I am using a collectionView to display these images. However, when this image array reaches the 20th or so image, it crashes. I believe this is due to a memory issue.. How do I store the images in an image array in a way which is memory efficient?
Michael Dauterman provided an answer using thumbnail images. I was hoping there was a solution besides this. Maybe storing the pictures into NSData or CoreData?
Camera.swift:
//What happens after the picture is chosen
func imagePickerController(picker:UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject:AnyObject]){
//cast image as a string
let mediaType = info[UIImagePickerControllerMediaType] as! NSString
self.dismissViewControllerAnimated(true, completion: nil)
//if the mediaType it actually is an image (jpeg)
if mediaType.isEqualToString(kUTTypeImage as NSString as String){
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
//Our outlet for imageview
appraisalPic.image = image
//Picture taken, to be added to imageArray
globalPic = image
//image:didFinish.. if we arent able to save, pass to contextInfo in Error Handling
if (newMedia == true){
UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil)
}
}
}
NewRecord.swift
var imageArray:[UIImage] = [UIImage]()
viewDidLoad(){
//OUR IMAGE ARRAY WHICH HOLDS OUR PHOTOS, CRASHES AROUND 20th PHOTO ADDED
imageArray.append(globalPic)
//Rest of NewRecord.swift is code which adds images from imageArray to be presented on a collection view
}
I've run into low-memory problems myself in my own apps which have to work with a number of high resolution UIImage objects.
The solution is to save thumbnails of your images (which take a lot less memory) in your imageArray and then display those. If the user really needs to see the full resolution image, you could allow them to click through on the image and then reload & display the full size UIImage from the camera roll.
Here's some code that allows you to create thumbnails:
// image here is your original image
let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(0.5, 0.5))
let hasAlpha = false
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
image.drawInRect(CGRect(origin: CGPointZero, size: size))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
imageArray.append(scaledImage)
And more information about these techniques can be found in this NSHipster article.
Swift 4 -
// image here is your original image
let size = image.size.applying(CGAffineTransform(scaleX: 0.5, y: 0.5))
let hasAlpha = false
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
image.draw(in: CGRect(origin: .zero, size: size))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With