Mitesh Dobareeya
Mitesh Dobareeya

Reputation: 1020

Unable to load locally stored images faster into collection view.?

I have a multiple images and video stored in application document directory. I am displaying that images and videos in collection view using SDWebImage in this way.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{


AlbumImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AlbumImageCell" forIndexPath:indexPath];
cell.albumImage.image=nil;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
if (cell == nil) {
    cell = [[[NSBundle  mainBundle] loadNibNamed:@"AlbumImageCell" owner:self options:nil] objectAtIndex:0];
}

NSInteger Type=[[[self.arrTbl_Album_Image objectAtIndex:indexPath.row] objectAtIndex:3] intValue];
if (Type==1) {
        cell.imgPlay.hidden=YES;
        [cell.albumImage setImage:[images objectAtIndex:indexPath.row]];
    }else{
        cell.imgPlay.hidden=NO;
        [cell.albumImage setImage:[images objectAtIndex:indexPath.row]];
    }

    return cell;
}

Here code for generating thumbnail.

-(void)load_Album_Data{
       NSUserDefaults *album_id=[NSUserDefaults standardUserDefaults];
       NSInteger Album_id=[album_id integerForKey:@"album_Id"];

//From the query.
NSString *query=[NSString stringWithFormat:@"select * from tbl_Album_Image where album_id='%ld' order by id desc",Album_id];


//Get result.
if (self.arrTbl_Album_Image != nil) {
    self.arrTbl_Album_Image=nil;
}
self.arrTbl_Album_Image=[[NSArray alloc]initWithArray:[self.dbManager loadDataFromDB:query]];


dispatch_queue_t myQueue = dispatch_queue_create("MyQueue",NULL);
dispatch_async(myQueue, ^{

for(int i=0;i<self.arrTbl_Album_Image.count;i++)
{
    NSInteger AssetType=[[[self.arrTbl_Album_Image objectAtIndex:i] objectAtIndex:3] intValue];
    if (AssetType==1) {
       //for image 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *inputPath = [[self.arrTbl_Album_Image objectAtIndex:i]objectAtIndex:2 ];

    NSString *imageEx=[inputPath pathExtension];
    NSString *imageName=[[inputPath lastPathComponent]stringByDeletingPathExtension];

    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@",imageName,imageEx]];

    UIImage *img=[UIImage imageWithContentsOfFile:fullPath];
    CGFloat scale = MAX(106/img.size.width, 106/img.size.height);
    CGFloat width = img.size.width * scale;
    CGFloat height = img.size.height * scale;
    CGRect imageRect = CGRectMake((106 - width)/2.0f,
                                  (106 - height)/2.0f,
                                  width,
                                  height);
    CGSize c=CGSizeMake(106, 106);
    UIGraphicsBeginImageContextWithOptions(c, NO, 0);
    [img drawInRect:imageRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    [images addObject:newImage];
    }
    else{
        //for video 
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *inputPath = [[self.arrTbl_Album_Image objectAtIndex:i]objectAtIndex:2 ];

        NSString *imageEx=[inputPath pathExtension];
        NSString *imageName=[[inputPath lastPathComponent]stringByDeletingPathExtension];

        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@",imageName,imageEx]];

        NSURL *videoURL = [NSURL fileURLWithPath:fullPath];
        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];

        AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
        imageGenerator.appliesPreferredTrackTransform = YES;
        NSError *err = NULL;
        CMTime time = CMTimeMake(1, 2);
        CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:&err];
        UIImage *thumbNailImage = [[UIImage alloc] initWithCGImage:imageRef];


        CGFloat scale = MAX(106/thumbNailImage.size.width, 106/thumbNailImage.size.height);
        CGFloat width = thumbNailImage.size.width * scale;
        CGFloat height = thumbNailImage.size.height * scale;
        CGRect imageRect = CGRectMake((106 - width)/2.0f,
                                      (106 - height)/2.0f,
                                      width,
                                      height);
        CGSize c=CGSizeMake(106, 106);
        UIGraphicsBeginImageContextWithOptions(c, NO, 0);
        [thumbNailImage drawInRect:imageRect];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

             [images addObject:newImage];

    }

    dispatch_async(dispatch_get_main_queue(), ^{
             //Reload the Image view.
     [self.album_ImageView reloadData];
                   }


    });

}
});


 }

But the problem is i am unable to load images faster and also app is crash down when scroll up-down happen fast. And also for video image not generated. Please help me to solve this problem and provide me any solution. I want fast image loading in collection view cell.

Upvotes: 2

Views: 521

Answers (2)

Wain
Wain

Reputation: 119031

It seems like when you save the images from the photo library you should save the full size if you need it and save an appropriately scaled version of the image that you can use for display in the app. If using ALAsset that would likely be the thumbnail.

If you do that the image load will be quick and the memory usage minimal.

Currently you're simply trying to load too much image data into memory and that takes a long time and crashes the app when it inevitably runs out. Images taken with the device camera are actually very large...

Upvotes: 0

Moin Shirazi
Moin Shirazi

Reputation: 4425

Instead of ur code to set image change to this

 [cell.albumImage sd_setImageWithURL:imaURL placeholderImage:[UIImage imageNamed:@"placeholder.png"]  options:SDWebImageRefreshCached   completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

        dispatch_async(dispatch_get_main_queue(), ^{

            cell.albumImage.image=image;
        });
    }];

It will load faster and even saves in cache

Upvotes: 1

Related Questions