Reputation: 654
I have a collection view, which loads images from documents directory. When I try to laod these images to the collectionview, the app get crashed with a memory warning.
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
UIImage *cellImage;
if (indexPath.section == 0) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *folderPath = [documentsDirectoryPath stringByAppendingPathComponent:@"Photos"]; // subDirectory
NSString *filePath;
if ([[NSFileManager defaultManager] fileExistsAtPath:folderPath])
filePath = [folderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Photo%d",indexpath.row]];
cellImage = [UIImage imageWithContentsOfFile:filePath];
} else if (indexPath.section == 1){
cellImage = [UIImage imageNamed:@"btn_vid.png"];
} else if (indexPath.section == 2){
cellImage = [UIImage imageNamed:@"btn_mic.png"];
} else if (indexPath.section == 3){
cellImage = [UIImage imageNamed:@"btn_1.png"];
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:100];
[imageView setImage:cellImage];
return cell;
}
What am I doing wrong?
Update:
The images are good sized because I take it from the phone's camera and save in documents directory
UPDATE:
I have received the suggestion of adding thumnails for the images and then load them from Airsource Ltd. I used this code to generate the thumbnail images instead of his and it worked. But I would like to know, which one is better.
+(UIImage*) generateThumbnailFromImage:(UIImage*)theImage
{
UIImage * thumbnail;
CGSize destinationSize = CGSizeMake(80,80);
UIGraphicsBeginImageContext(destinationSize);
[theImage drawInRect:CGRectMake(0,0,destinationSize.width, destinationSize.height)];
thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return thumbnail;
}
Upvotes: 0
Views: 1564
Reputation: 32632
You're loading the full-sized image, but you're presumably only displaying a thumbnail. However, as things stand the UIImage needs to keep the full, decompressed image in memory in order to display the scaled down version, which is woefully inefficient.
To generate a thumbnail, load in the file as NSData, and then use the standard Apple code for generating thumbnails. Don't do too many in parallel., or you will hit exactly the same problem you already have
CGImageRef MyCreateThumbnailImageFromData (NSData * data, int imageSize)
{
CGImageRef myThumbnailImage = NULL;
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions = NULL;
CFStringRef myKeys[3];
CFTypeRef myValues[3];
CFNumberRef thumbnailSize;
// Create an image source from NSData; no options.
myImageSource = CGImageSourceCreateWithData((CFDataRef)data,
NULL);
// Make sure the image source exists before continuing.
if (myImageSource == NULL){
fprintf(stderr, "Image source is NULL.");
return NULL;
}
// Package the integer as a CFNumber object. Using CFTypes allows you
// to more easily create the options dictionary later.
thumbnailSize = CFNumberCreate(NULL, kCFNumberIntType, &imageSize);
// Set up the thumbnail options.
myKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
myValues[0] = (CFTypeRef)kCFBooleanTrue;
myKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
myValues[1] = (CFTypeRef)kCFBooleanTrue;
myKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
myValues[2] = (CFTypeRef)thumbnailSize;
myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
(const void **) myValues, 2,
&kCFTypeDictionaryKeyCallBacks,
& kCFTypeDictionaryValueCallBacks);
// Create the thumbnail image using the specified options.
myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource,
0,
myOptions);
// Release the options dictionary and the image source
// when you no longer need them.
CFRelease(thumbnailSize);
CFRelease(myOptions);
CFRelease(myImageSource);
// Make sure the thumbnail image exists before continuing.
if (myThumbnailImage == NULL){
fprintf(stderr, "Thumbnail image not created from image source.");
return NULL;
}
return myThumbnailImage;
}
Upvotes: 1