UIImage from NSData in UITableView - performance issue - ios

I am storing images from Photos Album in my app documents directory as NSData and than displaying them in UITableView. I have problem with performance. It takes a good few seconds to save image into app directory and I have same problem when than loading them into TableView. This is my code to store images:
//Convert UIImage to NSData
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
//Save image to app documents directory
NSError *error;
[imageData writeToFile:fullImagePath options:NSDataWritingAtomic error:&error];
That is how I load them into UITableView:
NSData *imageData = [NSData dataWithContentsOfFile:path];
UIImage *myImage = [UIImage imageWithData:imageData];
cell.imageView.image = myImage;
What may cause these performance issues? Is it any other way to store and retrieve images from app documents directory?

Two approaches:
First you might consider scaling down the images before you save them, or save an additional smaller copy for display in the table view. It depends how good images you need - presumably for the table view not as large as full scale pictures with MB of data. Actually, the images will also look better if they are properly scaled. This by itself should take care of the delays.
Second, you might consider loading the images asynchronously. Maintain a mutable array of images to be downloaded. Create a singleton that does the download and notifies the table view when finished. Set cell.imageView.image in the notification (or delegate) callback.

Related

How to convert UIImage to NSData when the image's type is gif?

I've searched for so much articles about converting UIImage to NSData.There are some solutions.But when I only know the (UIImage*) image object , how could I configure it's NSData correctly especially when it's type is gif.
-(void)convertUIImageToNSData:(UIImage* )image{
//if the image's type is gif,how to get it's data
NSData *data = ?
}
Gif is not supported in ios, it will treat the file as a normal file and also wont be store as UIImage without lib or something, you can just use dataWithContentsOfFile it to make it become NSData
Finally, I got the nsdata of an image by pass the original data when I just pick an picture from system album. That's little not so elegant.

Quick way to load images

Right now I'm loading images view a file url and its taking a long time. I've even put it on the main thread as a high priority but its still slow. This is actually in a loop for like 6 images. My question is:
Is there a faster way to load images to a view than this? Like an alternative to a file url?
//check the filetype
if ([fileType isEqual: #"image"])
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//get image
NSURL *imageFileUrl = [[NSURL alloc] initWithString:file.url];
NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageWithData:imageData];
});
});
}
My images are at a quality of this preset and the size is the size of the iphone screen whether that be a 5,6,or 6 plus
self.camera = [[LLSimpleCamera alloc] initWithQuality:AVCaptureSessionPreset1280x720
position:CameraPositionBack
videoEnabled:YES];
thanks,
While there isn't any shortcut to loading the images there are things you can do to help.
Initially only load the image that are visible, after that load any that may be visible soon.
If the size of the image is larger than the view create a smaller image, perhaps a couple for different screen resolution devices.
Create a low resolution image versions, load them first to get something up for the user and then load the full resolution images replacing the low resolution version..
Please, Add the sizes of the images and the sizes of the UIImageView and screen resolution to the question.
What can I suggest you that,
Save the duplicate copy of each image in lower resolution/Size on
server.
Load the duplicate image on first load.
When user particularly views an image, load original image then.

imageWithContentsOfFile memory issue

My project is having image sharing functionality. In this functionality my app asks the user from which library you want to share.
I wrote below code to assign image, retrieved from Default library/Custom library.
Device default library
imgVwMediaFile.image = [UIImage imageWithCGImage:[asset thumbnail]; //(ALAsset *)asset
Custom library (images are at Documents/image/user)
imgVwMediaFile.image = [UIImage imageWithContentsOfFile:path];
//(NSString*)path
App displyas this images in collection view having custom cell.
When i select app custom library then images are retrieves from Documents directory ,but imagewithcontentofFile cosuming around 90 to 100 Mb memory.
In other case when i select app default libray, it is not cosuming more then 8 or 10 Mb memory.
I tried diffrent code from stack Q/A for custom library, but still memory issue is there.
-1-
CGImageRef iref = [[UIImage imageNamed:asset] CGImage] ;
imgVwMediaFile.image=[UIImage imageWithCGImage:iref];
iref=nil
-2-
NSData *imageData = [[NSData alloc] initWithContentsOfFile:path];
imgVwMediaFile.image=[UIImage imageWithData:imageData];
imageData=nil
-3-
imgVwMediaFile.image=[UIImage imageNamed:path];
So please guide me that, how can i load images from document dir ?
What are the best way to load images from document dir without increasing memory load ?
The problem is that yhe images you have saved to disk are large, so loading lots of the, to display in a collection takes a lot of memory. You use thumbnails from the built in library so you see a different result.
Ideally you would save a folder of thumbnails in your custom library and display those, then, when an image is selected, get the corresponding full size image to use (this is the approach basically all photo libraries use). Alternatively you can resize the images on-the-fly, but your scrolling is basically guaranteed to suck.
UIImage *img = [UIImage imageWithContentsOfFile:path];

iPhone app memory leak with UIImages in NSMutableArray

I have an NSMutableArray that contains images. I then have an image view that displays images from that array. However, I am getting a big memory leak each time it loads the image view. I am not sure how to correct that. I am using ARC in Xcode 5.0.2.
_image1 = [UIImage imageNamed:#"FirstImage.png"];
imagearray = [[NSMutableArray alloc] init];
[imagearray addObject:_image1];
_imageview1 setImage:[imagearray objectAtIndex:0]];
The memory leak issue might be due to the UIImage not getting nil. For that, you have to initialize UIImage with alloc and after adding it to the array, make it nil. You can prevent you memory leak in this way:
UIImage *image1 =[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]pathForResource:#"FirstImage" ofType:#"png"]];
[imagearray addObject:image1];
_imageview1 setImage:[imagearray objectAtIndex:0]];
image1 =nil;
Please let me kniw if it works. Thanks :)
From apple doc:
+ (UIImage)imageNamed: method looks in the system caches for an image object with the specified name and returns that object if it exists.
If a matching image object is not already in the cache, this method
loads the image data from the specified file, caches it, and then
returns the resulting object.
If you have an image file that will only be displayed once and wish to
ensure that it does not get added to the system’s cache, you should
instead create your image using imageWithContentsOfFile:. This will
keep your single-use image out of the system image cache, potentially
improving the memory use characteristics of your app.
So as a suggestion, if you replace the imageNamed: with imageWithContentsOfFile: to avoid caching, your memory footprint should improve

NSCoding UIImage to disk takes up huge amount of disk space and writes slowly

I am serializing UIImages to disk using NSKeyedArchiver.
UIImage conforms to NSCoding so serializes+deserializes properly but the resulting file is quite large causing performance issues.
I tested this by loading images from the ALAssetsLibrary taken on a standard iPhone5 camera to a UIImage and then serializing images to disk
UIImage *testImage = [asset defaultRepresentation]....
[NSKeyedArchiver archive:testImage ....]
The files were ~15MB and took over 1 second to write/load.
Then I tried serializing the UIImage by converting to NSData:
NSData *imageData = UIImageJPEGRepresentation(UIImage *image, 0....1); // tried most compression all the way to least compression
[NSKeyedArchiver archive:imageData....]
The resulting files were magnitude smaller (so faster to read and write)
What is the suggested way to save images? are the underlying images from the ALAssetsLibrary also taking 15MB on disk to store the images?
Should I be using PNG representation?

Resources