Reputation: 5795
I'm working on GIF viewer but I have a problem with thumbnail images. They are not animated, but when I set huge gif as image to imageView it still takes a lot of time and interface lags.
Here is my method how I do this:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:@"Cell"
forIndexPath:indexPath];
UIImage *image;
NSData *data = [NSData dataWithContentsOfURL:self.dataSource[indexPath.row]];
image = [UIImage imageWithData:data];
myCell.myImageView.image = image;
return myCell;
}
URL is local and as I have found out the bottleneck here is that setting huge gifs (few megabytes each) as uiimage is expensive and takes time.
How do I optimize this? I want to create lightweight thumbnail non animated images from the image GIF data I have. How do I go about this?
EDIT: Actually I have implemented cache to store them, but this is not ideal solution since I have to clear cache occasionally with memory warnings. My question is still valid. Here is the code I have for now:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:@"Cell"
forIndexPath:indexPath];
UIImage *image;
if ([self.cache objectForKey:self.dataSource[indexPath.row]]) {
image = [UIImage imageWithData:[self.cache objectForKey:self.dataSource[indexPath.row]]];
} else {
NSData *data = [NSData dataWithContentsOfURL:self.dataSource[indexPath.row]];
image = [UIImage imageWithData:data];
}
myCell.myImageView.image = image;
return myCell;
}
Upvotes: 0
Views: 857
Reputation: 91
In order to display thumbnails quickly, you need to create a thumbnail of the image when it is downloaded and cache it on disk. In the case of an animated GIF, you probably just want to grab the first frame, scale it down until it is only a few kilobytes, cache it to disk, and then display it. Something like this (untested code):
NSData *imageData = ...; // wherever you get your image data
UIImage *originalImage = [UIImage imageWithData:imageData];
CGSize originalSize = originalImage.size;
CGSize scaleFactor = 0.25f; // whatever scale you want
CGSize newSize = CGSizeMake(originalSize.width * scaleFactor, originalSize.height * scaleFactor);
UIGraphicsBeginImageContext(newSize);
CGRect newFrame = CGRectZero;
newFrame.size = newSize;
[originalImage drawInRect:newFrame];
UIImage *shrunkImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *pngDataToBeCached = UIImagePNGRepresentation(shrunkImage);
Loading the resulting PNGs should be very fast. Save them into the caches folder to make sure they don't get backed up into iTunes. Also keep in mind that the process of scaling and caching the images can happen on a background thread to avoid blocking the UI.
Upvotes: 3