How to optimize flipping through 50+ images, which are downloaded - objective-c

I have an iPad app with about 50+ full screen images(png) and I want to be able to flip back and forward between the images. To make the app size smaller I am downloading the images as I need them, using NSURLConnection. I also cache about 15 images. The problem I am running into is that even though I have a cache it is quite easy to flip through the cache and to an image that has not been downloaded yet.
I am wondering what suggestion you have to fix my problem. Should I just increase the cache or should I down res the images? Do I have to limit the number of images I am downloading at the same time? Many thanks!
This is how I start each image download
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest
requestWithURL:[NSURL URLWithString:theUrlString]]
delegate:self startImmediately:NO];
[conn scheduleInRunLoop:[NSRunLoop mainRunLoop]
forMode:NSRunLoopCommonModes];
[conn start];

Concerning the flipping through the photos once they have been downloaded, here are a few tips to try.
Have both a low resolution and a high resolution version of the photo available.
Whenever you have one picture loaded, bring the highres versions of its immediate neighbors into memory. In otherwords, load, but don't display those pictures.
Load the low resolution images into memory of some range surrounding the displayed picture. So if picture 5 is displayed, and your range is 5, load lowres pictures 0 through 10
While a user is flipping through, render the low resolution first, and then load the high resolution picture.
These tips should account for a user flipping through a few pictures to find the desired photo, and then pausing on a select picture, and then flipping through some more.

Related

App crashing on ipad when downloading images

im using the sdwebImage library to download images in tableview cell and display them.
the images are high resolution images. when the app launches, and starts loading, it suddenly crashes, without giving any errors, except sometime giving "received memory warning", and then the app crashes, its running on the simulator normally, but on an ipad, it is crashing,
the code where im putting the image in the cell:
- (void)setCellWithImage:(NSString *)imageURL
{
if (imageURL && [imageURL length]) {
[self.testingImageView sd_setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:[UIImage imageNamed:#"ic_launcher"]];
}
}
any idea how to solve this issue?
I will suggest you to show in tableview use low quality image.
Get two image paths one for low quality image and another for high quality image. Show low quality image in Tableview and on click of particular image show high quality image.
There is only difference between simulator and phone is, Simulator doesnt have memory so on simulator this issue will not replicate.

Fast animation with big images

I have a task to make simple animation for iPad2 like here:http://www.subaru.jp/legacy/b4/index2.html
User can simply slide to left and right and object visually rotates by it's vertical axis. I think simpliest way to do this is to use a UIImage or CCSprite from cocos2d, set array with images and to change images depends on touches. The size of images planned to be 1024x768(full screen)and at least 15-20 images per second for smoother animation. Question is: is it possible to do this really smooth this way? What is the real limit for iPad2 for such a thing. And if it's behind the bounds how can I realize this behavior other way?
Ok, let's run the math:
15 times 1024x768 images per second. If you use 4096x4096 texture atlases you can put them all into a single texture atlas. That covers 1 second.
That means you need to load another texture atlas every second. At most you can have 2-3 such texture atlases in memory (conservatively each uses 64 MB memory).
Really the only way to make this feasible is to use .PVR.CCZ texture atlases to increase load times and reduce memory usage. You'd still have to load/unload texture atlases frequently (within a few seconds). So you should do a test how fast loading the 4k .PVR.CCZ texture is and whether that will impact speed.
If that's too slow (which I suspect it will be) you'll have to use 1024x1024 .pvr.ccz textures (single frames) and keep caching 4 or more of them ahead of time using the CCTextureCache async methods (and uncache the texture you're currently replacing) so that the loading of new textures occurs in the background and doesn't affect animation speed.
Since this is about rotation, you'd have to ensure that at least one, better two frames to either direction are in the cache. Since rotation can happen at various speeds, the user might still experience delays regardless.
You should further reduce color bit depth of the textures as much as possible until it affects image quality too much.
If you apply every trick in the book, I'm sure it's doable. But it's not going to be as simple as "play animation" and be done with it. If that's what you wanted to know.
I've did something like this before, but using a JS library with UIWebView control, the library name is UIZE, check this example. I've used it with around 100 image with size 1024 × 655 and it's so smooth.
Download the library from the size, organize the folders as the following:
rotation3d
example
3d-rotation-viewer.html
images
Images files
js
The library files.
In your objective-C class, use the following code to load the html page in the UIWebView:
NSString *path = [[NSBundle mainBundle]
pathForResource:#"3d-rotation-viewer"
ofType:#"html"
inDirectory:#"rotation3d/example" ];
NSURL *urls = [NSURL fileURLWithPath:path];
NSString *theAbsoluteURLString = [urls absoluteString];
NSString *queryStrings = #"?param1=something";//Parameters to pass to your html page
NSString *absoluteURLwithQueryString = [theAbsoluteURLString stringByAppendingString: queryStrings];
NSURL *finalURL = [NSURL URLWithString: absoluteURLwithQueryString];
NSURLRequest *request = [NSURLRequest requestWithURL:finalURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:(NSTimeInterval)10.0 ];
[webViews loadRequest:request];

what's the different between "cached image" and "local image"?

I am beginner. I want to show images by urls on TableView, so I use AFNetworking+SDURLCache, just as below
// init URLCache
SDURLCache *URLCache = [[SDURLCache alloc] initWithMemoryCapacity:1024*1024*2 diskCapacity:1024*1024*20 diskPath:[SDURLCache defaultCachePath]];
[URLCache setIgnoreMemoryOnlyStoragePolicy:YES];
[SDURLCache setSharedURLCache:URLCache];
========================================================
// set cell
[cell.imageView setImageWithURL:[NSURL URLWithString:IMAGE_URL] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
[[SDURLCache sharedURLCache] cachedResponseForRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:IMAGE_URL]]];
Here, I use a image on all different cells. Everything works OK! When I run my project first time, displaying images on cells need long time because my web image very large. When I run my project second time, I found that TableView load images one by one immediately
? Why?why not load all images once immediately. I replaced the cached image to local image, TableView load images at a time. what's the different between "cached image" and "local" image? SDURLCache did't work?
I have no iOS experience, but I would presume a cached image is an image that is stored in the web client's cache so that it will load that resource faster, unless that resource has been modified and the cached version invalidated since it was put in the cache.
A local image, I would assume, is an image stored on the device itself. Obviously this will be faster than downloading it as storage on the iDevices is comprised of NAND flash chips and such, which far outstrip a domestic Internet connection.

Objective - C, fastest way to show sequence of images in UIImageView [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to efficiently show many Images? (iPhone programming)
I have hundreds of images, which are frame images of one animation (24 images per second). Each image size is 1024x690.
My problem is, I need to make smooth animation iterating each image frame in UIImageView.
I know I can use animationImages of UIImageView. But it crashes, because of memory problem.
Also, I can use imageView.image = [UIImage imageNamed:#""] that would cache each image, so that the next repeat animation will be smooth. But, caching a lot of images crashed app.
Now I use imageView.image = [UIImage imageWithContentsOfFile:#""], which does not crash app, but doesn't make animation so smooth.
Maybe there is a better way to make good animation of frame images?
Maybe I need to make some preparations, in order to somehow achieve better result. I need your advices. Thank you!
You could try caching say 10 images at a time in memory (you may have to play around with the correct limit -- i doubt it's 10). Everytime you change the image of the imageView you could do something like this:
// remove the image that is currently displayed from the cache
[images removeObjectAtIndex:0];
// set the image to the next image in the cache
imageView.image = [images objectAtIndex:0];
// add a new image to the end of the FIFO
[images addObject:[UIImage imageNamed:#"10thImage.png"]];
You can find your answer here: How to efficiently show many Images? (iPhone programming)
To summarize what is said in that link, you get better performance when showing many images if you use low level API's like Core Animation and OpenGL, as oppose to UIKit.
You could create a buffer of several images using an array. This buffer array of images can be loaded/populated using imageWithContentsOfFile from a background thread (a concurrent GCD asynchronous, for example).

Objective-c : Load part of an image file

I searched in the CG API but i did not found any way to load only a subset of pixels in a given image.
I need to load a really big image in openGL AT RUNTIME (the requirement is that i can't resize it at compile time). The texture size is too big ( > GL_MAX_TEXTURE_SIZE) so i subdivide it in other smaller images so openGL doesn't complains.
Right now this is what i do to load the big image:
NSData *texData = [[NSData alloc] initWithContentsOfFile:textureFilePath];
UIImage *srcImage = [[UIImage alloc] initWithData:texData];
And then i use CG to subdivide the image using CGImageCreateWithImageInRect() ... and its ready to be sent to openGL.
The problem is that on iPod touch the app crashed because its taking too much memory after loading the big image. I would like to load only the pixels of interest without having to create a huge peak of memory, then i can release the memory and load the next chunk that i need. Someone knows if it is possible?