Reputation: 3575
I am making an app who's main function is displaying large images in a tableview, some can be 1000 pixels wide and 1MB+ in size.
I am finding that older devices (3GS) has serious trouble handling these and quickly sends out memory warnings.
I can't get around what images are being brought in, but I thought I could make them smaller both in dimension and file size. So I looked into
NSData *dataForJPEGFile = UIImageJPEGRepresentation(img, 0.6)
for compressing, but I don't think this helps with the memory warning
and resizing like:
UIImage *newImage;
UIImage *oldImage = [UIImage imageWithData:imageData] ;
UIGraphicsBeginImageContext(CGSizeMake(tempImage.size.width,tempImage.size.height));
[oldImage drawInRect:CGRectMake(0, 0,320.0f,heightScaled)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
and also with https://github.com/AliSoftware/UIImage-Resize
Basically I want to take an image and reformat so that its smaller and in dimension and filesize on the fly, then delete the old one. Is this the best way to do it? Would caching the images help? Like with https://github.com/rs/SDWebImage ?
Upvotes: 2
Views: 2861
Reputation: 5654
You can use CGImageSourceCreateThumbnailAtIndex
to resize large images without completely decoding them first which will save a lot of memory and prevent crashes/memory warnings.
If you have the path to the image you want to resize, you can use this:
- (void)resizeImageAtPath:(NSString *)imagePath {
// Create the image source (from path)
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);
// To create image source from UIImage, use this
// NSData* pngData = UIImagePNGRepresentation(image);
// CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
// Create thumbnail options
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
(id) kCGImageSourceCreateThumbnailWithTransform : @YES,
(id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
(id) kCGImageSourceThumbnailMaxPixelSize : @(640)
};
// Generate the thumbnail
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
// Write the thumbnail at path
CGImageWriteToFile(thumbnail, imagePath);
}
More details here.
Upvotes: 3
Reputation: 628
The table view image should be resized, of course, it even makes it look better than a big image in a small frame. Now if storage is a problem and you have a server where you can download the large images from whenever you need, you could implement some sort of caching in the file system. Only store up to n-MB of images in there and whenever a new one is requested that is not currently in the file system, remove the least recently used (or something) and download the new one.
Ps: don't use +[UIImage imageNamed:]
. It has some bugs in its caching algorithm or something where it doesn't release the images you load using it.
Upvotes: 0