1

I'm rendering 60 images and getting a memory warning. Is there a better approach to my code below?

- (void)change{
    for (int aniCount = 1; aniCount < 60; aniCount++) {
        if ([UIScreen mainScreen].bounds.size.height == 568) {
           self.renderString = [NSString stringWithFormat: @"%i_5.png", aniCount + 1];
           self.imageView.image = [UIImage imageNamed:@"1_5.png"];
        }else{
            self.renderString =  [NSString stringWithFormat: @"%i.png", aniCount + 1];
        }
        // here is the code to pre-render the image
        UIImage *frameImage = [UIImage imageNamed:self.renderString];
        UIGraphicsBeginImageContext(frameImage.size);
        CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
        [frameImage drawInRect:rect];
        UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        [self.menuanimationImages addObject:renderedImage];
    }

    self.imageView.animationImages = [NSArray arrayWithArray: self.menuanimationImages];
 }

This method is called in my - (void)viewDidLoad

An example of what the app screen looks like: https://www.youtube.com/watch?v=2f80UcLhOW8

DevC
  • 6,982
  • 9
  • 45
  • 80
  • Are all 60 images displayed on the screen at the same? If so cache the images at the size required to display, if not only draw the images that are visible. – Joe Feb 07 '14 at 17:15
  • No what happens is that once a button is pressed, the imageview changes displaying each image in animation, one at a time. – DevC Feb 07 '14 at 17:20
  • Your suggestion is good but i am not too experience with caching. COuld you suggest? – DevC Feb 07 '14 at 17:20
  • Here is a related post on caching: http://stackoverflow.com/questions/11511548/best-way-to-cache-images-on-ios-app – Joe Feb 07 '14 at 17:22
  • 1
    dont render them all at once - easy ;) you only eve need 1 + a few for faster browsing – Daij-Djan Feb 07 '14 at 17:38

1 Answers1

2

Do we infer from the check of the screen resolution that these are full screen images? If so, to do a full screen animation with 60 images requires an extraordinary amount of memory, and I'm not surprised you'd get memory warnings. Each image, when used in a UIImageView will require at least four bytes per pixel.

For non-retina images on 4" screen, that would require roughly 42mb for 60 full screen images. If those are retina images (with twice the resolution) that jumps to 166mb. Don't look at the size of the PNG files when considering the amount of memory used, because PNG files have some compression, but they'll be uncompressed when you use them in your app.

Generally you would not want to animate use that many full screen images. You would want to probably consider programmatically animating the view using UIKit animation or Core Animation (or other similar technologies). Or, if you really have to use a sequence of images, see if you can constrain the portion that's animated to a smaller portion of the screen, thus using smaller images and requiring far less memory.

It's hard to say without knowing what the animation looks like. If you describe the animation (or show us a screen snapshot or two), we can probably suggest far less memory intensive approaches.


In your comments you shared a link to a video that features the desired kaleidoscopic effect. A couple of thoughts:

  1. I'd first focus on programmatic ways to render kaleidoscopic effects. Given the complexity here, this might lead me to research "OpenGL ES" approaches for rendering this kaleidoscopic effect. You might even chance upon some existing implementations.

  2. I notice that there are Core Image filters for CIKaleidoscope and CITriangleKaleidoscope that might be useful in generating the effect you're looking for (see the Core Image Filter Reference for information on those two filters). I don't think those will be quite right here, but work checking out.

  3. Failing the above attempts to programmatically render the kaleidoscope, it strikes me that, at the very least, you could reduce memory requirements of your current implementation by a factor of four given that the the kaleidoscope-effect seems to be both horizontally and vertically symmetric. So you could theoretically have a sequence of images for the upper left quadrant, and then render the other three as transforms of the same image.

  4. Or you could alternatively create a full screen video and use the media player framework to play it.

I'd probably exhaust those lines of inquiry before I pursued doing a animation via a sequence of full screen images. The full screen images is just going to be a memory inefficient way to tackle this sort of problem, and you're almost certainly likely to run into challenges. And if you ever consider iPad rendition of the app or want to consider longer sequences, the approach of a series of full screen images is likely to be entirely untenable.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • The animation is indeed full screen,you are correct. It is required to be full screen however so I have no alternative with making the size of the image smaller. The image is the size of the screen, with both non retina and retina versions, once a button is pressed, it flicks through all images. Almost like how movies would be made years ago. – DevC Feb 07 '14 at 17:46
  • hers an example of what the app does: https://www.youtube.com/watch?v=2f80UcLhOW8 – DevC Feb 07 '14 at 18:01
  • @Gman Thanks for sharing the link to the video. I'd definitely consider a programmatic way to generate this kaleidoscopic effect. If your research in those areas don't yield results, I'd suggest you post a new question focusing on kaleidoscopic effects, outlining what you researched and tried, and solicit recommendations on how to proceed. But it seems unlikely to me that a series of full screen images is ever likely to be a fruitful approach (although I understand why you started with it, as it enjoys a certain simplicity). – Rob Feb 07 '14 at 19:06
  • Thanks for such great feed back! – DevC Feb 07 '14 at 19:09