Hello,
we've been writing a program for quite a long time now. And we won't get it finished because we have trouble drawing a small part of a large image file:
Our Xcode project holds a large image (.gif, about 4700x3100 pixels, 6MB). The file cannot be made smaller because we need this resolution. We have to draw a small part of it on the screen again and again, on avarage every 20 seconds. Our program does some calculation what part of the large image is relevant (actually it calculates the origin and the size of a small rectangle within the large picture). Then we draw this part on the screen.
For the drawing part we are using Quartz:
Code:
UIImage* largePic = [UIImage imageNamed:@"largePic.gif"];
CGImageRef _imageRef = CGImageCreateWithImageInRect(largePic.CGImage, rectOfPicToLoad);
CGContextDrawImage(_context, CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height), _imageRef);
CGImageRelease(_imageRef);
The drawing takes about 300ms. As we don't want the user to expirience any delay we put the calculation and the drawing part into a separate thread.
It works all well in the iPhone Simulator. Our program does what it should, it is performant and Instruments tells us that the overall size in memory was 2.5MB. Perfect! What is not perfect is the fact that out program crashes on the device. It crashes after a short, but not predictable time. "Program exited with status value:101." The device console logged it: <10% memory available. Therefore it got killed. A crashreport was generated:
Code:
PID:1421 RPRVT:55.3M RSHRD:7.84M RSIZE:56.2M Command:REDproj
Also, the Apple UIImage Reference says programmers shouldn't use UIImage for images larger than 1024x1024 pixels. I guess the UIImage class does some caching which doesn't get displayed in Instuments (remember that our program does not crash in iPhone Simulator!). So we replaced the UIImage part with:
Code:
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
NSString *path = [NSString stringWithString:[[NSBundle mainBundle] pathForResource:@"largePic" ofType:@"gif"]];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithString:path]];
CGDataProviderRef dp = CGDataProviderCreateWithURL((CFURLRef) url);
CGImageRef _imageRef = CGImageCreate(4678, 3090, 8, 8*4, 4678*4, cs, kCGImageAlphaLast, dp, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(dp);
CGColorSpaceRelease(cs);
_imageRef = CGImageCreateWithImageInRect(_imageRef, rectOfPicToLoad);
CGContextDrawImage(_context, CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height), _imageRef);
CGImageRelease(_imageRef);
It also crashes because of too less memory after some while but with the difference that it takes about 1 minute to draw the pictures

. Unacceptable.
Who knows a strategy to load a small rectangle out of a very large picture without crashes and which is as fast as the UIImage class?