PDA

View Full Version : How to make an animation?




HARDWARRIOR
Dec 29, 2008, 12:07 PM
Hi!
I need to make an animation on iPhone. It should be pausable. So UIImageView.animationImages and MPMoviePlayerController are useless. Also animation fps should be >= 15 fps.
1) I tried to use CGContextDrawImage for view, but fps were < 10.
2) Tried to assign image to UIImageView on timer: imageView.image = [UIImage imageWithContentsOfFile... fps again < 10.
3) Wanted to fill images in array first for(NSUInteger k = 1; k <= lastFrameNum; k++) {
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Fire %.3d", k * 4] ofType:@"png"]];
[images addObject:image];
} and then change them by timer - (void)nextAnimationFrame:(NSTimer *)timer {
if (frameNum > lastFrameNum - 1)
frameNum = 0;

imageView.image = [images objectAtIndex:frameNum];

frameNum ++;
, but faced 2 problems: I use 320x480 32bpp images. One animation period has 100 such images. First of all I have low memory warnings and my app slows down and quits. Sometimes iPhone reboots. Low memory warning happens in timer's selector - so I cant say that simply images array is big. I think imageview uses some kind of caching and because of this memory becomes full. Actually do not even know how to cope with low memory warnings - no maximum allowed level of allocated memory is shown in xcode's instruments. I have no leaks in my code (tested with instruments and Clang Static Analyzer) and no caches or enything that can be freed on low memory warning. Empirically I found out that no low memory warnings are rised if I use 25 images instead of 100. But for smooth animation I want all 100 of them at moderate fps >= 20. SEcond problem with imageView is that first pass of animation is performed slowly and only after that it becomes fast. Here I again come to thought about imageViews caches. It kind of caching all images that were assigned to it's image property?
4) I tried to add imageViews to viewController's view as as subviews each containing one frame of animation: for(NSUInteger k = 1; k <= 10; k++) {
NSString *fileName = [NSString stringWithFormat:@"Fire %.3d", k];
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:@"png"]];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
imageView.image = image;

[self.view insertSubview:imageView atIndex:(self.view.subviews.count + 1)];
}

and then to bring lowest to front on timer - (void)timerFired:(NSTimer *)timer {
[self.view bringSubviewToFront:[self.view.subviews objectAtIndex:0]];
}
Same problem here - low meory warning. And again it happens only during animation, not on adding subviews! And again I have to dramatically decrease frame number.

Now I am seeking for advice how to make pausable and fast (>= 20 fps) animation from 100 320x480 32bbp images with ability to throw couple of buttons in front it. Not mentioning video, because I dont know pausable video components. I am studiying opengl es now to find out is it to any use for such a task...



CommanderData
Dec 29, 2008, 04:08 PM
I'm afraid you'll get memory warnings no matter what you do with 100 images at 320x480x32bit... that is over 61MB of image data when decompressed in memory! Depending on what else is/was recently running (the web-browser, e-mail, and other background phone apps) you may only have about half of that available to you without memory warnings (I don't have hard numbers on that, just based on my experiences).

Is the entire screen changing completely every frame? Can you implement your animation as a series of much smaller frames drawn into the view at appropriate locations?

HARDWARRIOR
Dec 30, 2008, 01:35 AM
Unfortunately I can not reduce image size. Every frame has a unique picture and a minimum square it can fit into is 320x480.