views:

1662

answers:

3

Hi, i've been developing for the iphone platform for about 3 weeks now, and I'm trying to set up a frame by frame animation with 16 1000x1000 png images (with transparency) and plan on animating with around 100 later, so first I tried using imageNamed to animate all the images like this


-(IBAction)startClick1:(id)sender { cloud.animationImages = [NSArray arrayWithObjects: [UIImage imageNamed: @"g0000.png"], [UIImage imageNamed: @"g0001.png"], [UIImage imageNamed: @"g0002.png"], [UIImage imageNamed: @"g0003.png"], [UIImage imageNamed: @"g0004.png"],

Now this worked fine in the simulator, but when it came to the device the device just reboots when it first attempts the animation, probably from the known memory issues with imageNamed, so after doing some research I found out that imageWithContentsOfFile is supposed to not cache the images and hopefully won't cause the iphone to reboot when the animation is requested to play so I changed my code to something like this:

- (IBAction)startClick:(id)sender { gordon.animationImages = [NSArray arrayWithObjects: [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"g0001.png" ofType:nil] ], [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"g0002.png" ofType:nil] ], [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"ge0003.png" ofType:nil] ], [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"g0004.png" ofType:nil] ], [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"g0005.png" ofType:nil] ], [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"g0006.png" ofType:nil] ],

Now this runs buggy in the simulator and doesn't work on the device in the same way the imageNamed method did. So, what's the best and easiest way to animate a sequence of images that will run fine on the device? Oh and when answering remember that I'm new to this platform.

A: 

I had issues getting 3 transparent layers of 400x400 On the iphone, there is no way you can get 16 images of that size to work, so reassesing that should be first, second as for animation I use a repeating timer that calls every 24 seconds to render and set the rerender on the surface.

Robert Gould
Also the simulator is awesome at rendering compared with the device. Just because the simulator can handle something it doesn't mean the device can, at all.So first try to get one image on the phone then increase the array as needed.
Robert Gould
+2  A: 

One major difference between imageNamed: and imageWithContentsOfFile: is that imageNamed returns an image that has been pre-decompressed.

You can create your own "optimized" version without requiring the images to be cached by looking at this answer.

Now, I notice you're loading 1000x1000 images, but the screen size is only 320x480. Are you downscaling the image, cropping, or what? If you are downscaling, consider pre-downscaling the image. Also, is your animation meant to be 30fps, or is it more like a slideshow animation?

Finally, I would recommend loading up the frames of animation on demand. As you can see, 1000x1000 images take up too much memory to keep loaded optimized. If you only keep one in memory at a time, you won't crash, but you then have to be very careful about any pauses in your code. If you're doing a slideshow "ken burns" type effect, you can pre-optimize (decompress) one image for drawing for the duration of the slide.

If you're going for 30fps, you need to cut down the image size to get the speed up.

NilObject
I am trying to animate at around 15 fps, and the view I'm animating is moveable with touchesMoved, so the animation can't be just the size of the screen, because if the user drags the view to the side and then animates it the user will see the corners of the animation and it will look generally unprofessional. Is there another method of getting large size animations onto the iphone then? Like loading transparent video?
You can try chopping your 1000x1000 images into tiles so that you can only load the images you need. For example, splitting it into 200x200 images would cut down on the amount of pixels being loaded. As far as I know, there is no public API for doing transparent video on the phone
NilObject
Okay, Im not really sure what you mean by that.
The idea is to only load the region of the image that is needed. Since the iPhone screen is 320x480, by loading 1000x1000 images up, you're not using 85% of the image loaded ((320 * 480) / (1000 * 1000)). This is a major waste. If you split each image into smaller sections of the image, you can only load sections that are needed to be drawn, cutting down on 85% of your IO and memory load. It's harder to do than loading the entire image, but it may be necessary to get the speed you're looking for.
NilObject
I see, well, I think i'll go with creating my animation to be the size of the iPhone screen, and making it so the user won't be able to see the corners of the animation, and i'll see if the animation loads and preforms well, do you think if I take these steps it will work? If it doesn't when I try it then I'll try your suggested method of splitting the image, (which i'll probably need guidance form you to do)
Okay, I've resized my images and changed my animation to look in a way in which you can't see the corners, And hey presto, the iphone actually matches the simulator's performance, except for the fact that the first couple of frames of my animation are missed out and if you repeatedly tap the button that starts the animation the application quits or triggers a reboot, and obviously if i went on to sell my app that would be a problem, do you have any further optimization advice? Or for the performance I'm looking for do you recommend a different approach to animation?
A: 

Apple recommends always using an image program to resize your images, instead of the device. This takes a fair amount of processing power to do. That could be a major slow down, resizing 24 images in under a second.

Corey Floyd
I understand, but I am not resizing them with the device, they are the size they are required to be, my 1000x1000 images aren't resized to the size of the screen. But anyway, now I am animating images the size of the iphone screen, and that helped massively, but still the first few frames of my animation are missed, and when the user presses a button that starts the animation something is cached and megabytes of ram are lost and not released, so if the user keeps pressing that button which in my app they probably will, the device will reboot, or the app will quit.