Fastest way to load images into a UIView? - ios

i have a UIScrollView which holds different UIView container. Each container has to load six UIImages. When scrolling i need to adjust the contents within the "layoutSubviews" method.
Unfortunately loading these images affects in hiccups when the new container and the images will be created.
I´m loading the images async via "dispatch_async". I also used small 32x32px thumbnails which will be replaced with the full image 256x256px image. Unfortunately its stuttering..
Here´s the code of the "initWithFrame" method of such a UIView.
These UIViews will later be added as a subview to the UIView container.
// load ThumbnailImage and replace it later with the fullImage
NSString* thumbImageName = [self.data.imageName stringByAppendingString:#"_small"];
NSString* fileLocation = [[NSBundle mainBundle] pathForResource: thumbImageName ofType:#"png"];
UIImage* image = [UIImage imageWithData:[NSData dataWithContentsOfFile:fileLocation]];
[self setBackgroundImage:img forState:UIControlStateNormal];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSString* fileLocation = [[NSBundle mainBundle] pathForResource: self.data.imageName ofType:#"png"];
UIImage* image = [UIImage imageWithData:[NSData dataWithContentsOfFile:fileLocation]];
[self setBackgroundImage:img forState:UIControlStateNormal];
});
});
Is this the faster way to load images into a UIView?
How does Apple implemented the really fluid image view inside the "Photo.app" when scrolling between different fullscreen images?
I don´t know if it would make sense to use CoreImage?
Any advice would be great!
Thanks for any help and your time.
Have a nice day.

Related

UIImageView displays downloaded images from HTTP, but won't display image resource

In my first View Controller after a user logs in, there is a quick check to see if the user has uploaded a custom image to his account. (If he has, there's a URL in the user's profile data.)
These images are downloaded correctly in my code and they show up beautifully. The problem comes when there is no custom user image, and the VC tries to set the same UIImageView to a default picture (in xcassets). The picture is being loaded into the bundle, as far as I can tell, and it's a valid PNG file.
Here is the snippet for setting the image. If a custom URL is not found, I set the URL parameter string to "nil."
-(void) setImageWithUrl: (NSString *) Url Imageview: (UIImageView *) image {
if (Url.length > 4) {
NSURL *url = [NSURL URLWithString:Url];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *Profileimage = [UIImage imageWithData:data];
[image setImage:Profileimage];
}
else {
UIImage *Profileimage = [UIImage imageNamed:#"DefaultPicture"];
[image setImage:Profileimage];
}
}
This one's driving me nuts, so all weird ideas are welcome. :-)
Let me know if you want me to post any other parts of the code that you think could be a factor.
It looks like debug-need issue. But why don't you use any image download/cache library, like SDWebImage?
It gonna be much efficient and convenient

Is there any alternate for animating array of images using UIImageView?

UIImageView has animationImages for animating sequence of images. That works fine. But It holds the images object. So There is a spike in use of memory when this animation is happening. I tried NSTimer for setting image property of that image view, But it doesn't work.
Can we achieve this in any other approach?
Instead of looking for alternatives, just try to correct the existing code.
The best practice of allocating an image for animationImages should be using initWithContentsOfFile instead of imageNamed:
imageNamed: it cache’s your images and you lose control over the memory - there's no guarantee that releasing the object will actually release the image but does provide faster loading of images second time around as they are cached.
imageWithContentsOfFile: it does not cache images and is more memory friendly however as it does not cache images and the heavier images are loaded much slower.
When the animation does stop, just release the image collection array. If you are using ARC then make it the image collection array to nil.
Best Practice:
for(int itemIndex = 0; itemIndex < 20; itemIndex++) {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"myImage1" ofType:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];
[imageArray addObject:image];
}
After the Animation:
imageArray = nil;

Image Optimization (iOS)

I'm working on a iPad Magazine and I'm using a lot of images (background, slideshow and animation) and the memory utilized is very high.
I've read the following method uses a lot of memory
UIImage *picture = [UIImage imageNamed:#"myFile.png"];
And they recommended using this one
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:#"/myFile.png"];
imageView.image = [UIImage imageWithContentsOfFile:fullpath];
But I've found another method as well
imageView.image = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"myFile" ofType:#"png"]];
In order to optimize my app, which method should I use? All my images are .jpg and were saved for web in Photoshop.
All 3 methods will use the same amount of memory. The differences are the following:
Using [UIImage imageNamed:#"myFile.png"] image is cached in memory for faster reuse. This is good for small images used several times in your application (image background, etc). Cache is removed for non used images when memory warning is received.
Using [[UIImage alloc] initWithContentsOfFile:path] image is not cached and you can "force" release of memory by calling [image release] or setting property to nil using ARC. You have a better management of when memory is released
Using [UIImage imageWithContentsOfFile:fullpath] is just equivalent to [[[UIImage alloc] initWithContentsOfFile:path]autorelease]

iOS - UIImageView Animation receiving memory warning

I am attempting to run two UImageViews that have multiple arrays of animations they load and animate based on a selection the user makes. For example, here is one method:
-(void)initiateAnimations {
nullAnimation = [NSArray arrayWithObjects:
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0002" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0003" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0004" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0005" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0006" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0007" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0008" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0009" ofType:#"png"]],
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"null0010" ofType:#"png"]], nil];
}
And here is an IBAction calling the animation method:
-(IBAction)nullani {
player.animationImages = nullAnimation;
player.animationDuration = 0.50;
player.animationRepeatCount = 1;
[player startAnimating];
}
It all works well at first, but keep in mind i have about 5-6 other arrays of animations roughly with the same size images. They arent huge, ranging from 12-80k .png files. When i attempt to animate after a few times, I am recieving this error in the output:
2013-03-16 01:34:44.438 [3316:907] Received memory warning.
After i receive this message, any new animation loaded will crash the app.
I ran it through Instruments and was unable to find any leaks, and the output gives me nothing upon crash.
Is there any memory issues here? how can i get rid of this issue? thanks.
Some ideas:
1) Never have more than 1 animation loaded into an array. Once you stop one animation, and are ready to start another, delete the first animation and replace the image the viewer sees with the single image that should be showing. If you can determine the exact image that was showing (and am doubtful of this) then you can replace the array with a single image and the image will not flicker.
2) If you cannot do 1), then try using Core Animation directly (more work for you), and do the animation yourself. This gives you more control over memory usage (you could cache image bitmaps on the file system).
3) Using a Mac and AVFoundation or QTKit, make an animation from images, then create a "movie" that you start and stop instead of the image sequence. In this case you'd replace the static images in the bundle with movie objects.

image retrieved from url does not fit properly into UIImageView

I'm trying to download an image from an url and display into a cell (sample below):
NSURL *url = [NSURL URLWithString:#"http://images.google.com/intl/en_ALL/images/logos/images_logo_lg.gif"];
NSData *data = [NSData dataWithContentsOfURL:url];
[cell.imageView setImage:[UIImage imageWithData:data]];
Somehow when I display into the cell, it covers the whole cell, bigger than my UIImageView.
But If I display the image locally like below:
[cell.imageView setImage:[UIImage imageNamed:#"defaultProfile.png"]];
It fits perfectly into the UIImageView I set into the cell.
Why is this the case?
use scaleToFit property of imageview

Resources