views:

522

answers:

2

Is there any way to create a UIImage object from an offscreen surface without copying the underlying pixel data?

I would like to do something like this:

// These numbers are made up obviously...
CGContextRef offscreenContext = MyCreateBitmapContext(width, height);

// Draw into the offscreen buffer
// Draw commands not relevant...

// Convert offscreen into CGImage
// This consumes ~15MB
CGImageRef offscreenContextImage = CGBitmapContextCreateImage(offscreenContext);

// This allocates another ~15MB
// Is there any way to share the bits from the 
// CGImageRef instead of copying the data???
UIImage * newImage = [[UIImage alloc] initWithCGImage:offscreenContextImage];

// Releases the original 15MB, but the spike of 30MB total kills the app.
CGImageRelease(offscreenContextImage);
CGContextRelease(offscreenContext);

The memory is released and levels out at the acceptable size, but the 30MB memory spike is what kills the application. Is there any way to share the pixel data?

I've considered saving the offscreen buffer to a file and loading the data again, but this is a hack and the convenience methods for the iPhone require a UIImage to save it...

A: 

Maybe

UIImage *newImage = [[UIImage alloc[ initWithData:offScreenContext];
JoePasq
UIImage:initWithData takes an NSData* parameter, I haven't seen a way to get NSData* from CGImageRef or CGContextRef.
Shawn
The NSData comes in with image formats like JPEG and PNG, which you rean in via initWithData - going the other way, you get NSData* blocks out of a UIImage with PNGRepresentation and JPGRepresentation calls. So, it would not help you.
Kendall Helmstetter Gelner
A: 

You could try releasing the context right after you created the CGImage, releasing the memory used by the context, because CGBitmapContextCreateImage() creates a copy of the context.

Like this:

CGImageRef offscreenContextImage = CGBitmapContextCreateImage(offscreenContext);

CGContextRelease(offscreenContext);

UIImage * newImage = [[UIImage alloc] initWithCGImage:offscreenContextImage];

// ...

CGImageRelease(offscreenContextImage);
Philippe Leybaert
The CGBitmapContextCreateImage call is what allocated the big chunk of memory. Releasing anything there shouldn't have an impact on the initialization of the UIImage. This isn't the correct answer.So I tried something else. All of my previous results were with the 3.0 SDK. I compiled with the 3.1 SDK and my allocations went from a 15MB steady state with a 30MB spike to a 2MB steady state with a 6MB spike. Unbelievable!I went back and cleaned both versions to make sure my data was correct and it was. ObjectAlloc showed the same results. Looks like the 3.1 SDK fixed some memory issues.
Shawn