views:

399

answers:

2

I'm getting a "snapshot" of an UITextView as CGImage, but the problem is that the content of the UITextView is very long ( about ~110k contentSize.height ) and when I render the UITextView layer in to the context the memory usage becomes ~130MB which causes the application to crash when run on a device.

Here is the code. viewref is an instance of UITextView.

UIGraphicsBeginImageContext(self.viewref.contentSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();

//render the text
CALayer *tLayer = self.viewref.layer;
[tLayer renderInContext:ctx];

//get the "snapshot"
CGImageRef imageRef = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();

So, can I render only a partial of the UITextView layer to the image context ?

A: 

There are several ways to accomplish this. UITextView itself inherits from UIScroller, so you should be able to set the bounds to a particular region and just snapshot that region (just as if it were on screen).

How exactly are you creating the CGImage snapshot?

Dan Keen
+1  A: 

Try something like the following: (untested, but you'll get the gist)

CGSize contentSize = self.viewref.contentSize;
CGFloat verticalChunkHeight = 1024.0;
CGFloat verticalOffset = 0.0;

while (verticalOffset < contentSize.height)
{
    CGFloat height = fmin(verticalChunkHeight, contentSize.height - verticalOffset);

    UIGraphicsBeginImageContext(CGSizeMake(contentSize.width, height));
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(ctx, 0.0, -verticalOffset);
    CGContentClipToRect(ctx, CGRectMake(0.0, verticalOffset, contentSize.width, height));

    CALayer *tLayer = self.viewref.layer;
    [tLayer renderInContext:ctx];

    CGImageRef imageRef = [UIGraphicsGetImageFromCurrentImageContext() CGImage];

    // do something with imageRef

    UIGraphicsEndImageContext();
}
hatfinch