views:

3007

answers:

3

I'd like to create a UIImage object from the current graphics context. More specifically, my use case is a view that the user can draw lines on. They may draw incrementally. After they are done, I'd like to create a UIImage to represent their drawing.

Here is what drawRect: looks like for me now:

- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();

CGContextSaveGState(c);
CGContextSetStrokeColorWithColor(c, [UIColor blackColor].CGColor);
CGContextSetLineWidth(c,1.5f);

for(CFIndex i = 0; i < CFArrayGetCount(_pathArray); i++)
{
 CGPathRef path = CFArrayGetValueAtIndex(_pathArray, i);
 CGContextAddPath(c, path);
}

CGContextStrokePath(c);

CGContextRestoreGState(c);
}

... where _pathArray is of type CFArrayRef, and is populated every time touchesEnded: is invoked. Also note that drawRect: may be invoked several times, as the user draws.

When the user is done, I'd like to create a UIImage object that represents the graphics context. Any suggestions on how to do this?

+4  A: 

Hey, just use:

UIImage * image = UIGraphicsGetImageFromCurrentImageContext();

If you need to keep image around, be sure to retain it!

EDIT: If you want to save the output of drawRect to an image, just create a bitmap context using UIGraphicsBeginImageContext and call your drawRect function with the new context bound. It's easier to do than saving the CGContextRef you're working with within drawRect - because that context may not have bitmap information associated with it.

UIGraphicsBeginImageContext(view.bounds.size);
[view drawRect: [myView bounds]];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

You can also use the approach that Kelvin mentioned. If you want to create an image from a more complex view like UIWebView, his method is faster. Drawing the view's layer does not require refreshing the layer, it just requires moving image data from one buffer to another!

Ben Gotow
Thanks for the response, however doesn't seem to work. I added the line: _signatureImage = UIGraphicsGetImageFromCurrentImageContext();... where _signatureImage is a retained property. The returned object is nil. According to the docs, UIGraphicsGetImageFromCurrentImageContext() is intended for use only if the current context is a bitmap context. In my current implementation of drawRect: I don't believe that's the case. The docs mention the use of UIGraphicsBeginImageContext(), but I'm not sure how that applies in my case because drawRect may be invoked multiple times.
figelwump
+3  A: 

I think you may need to setup the graphics context first:

UIGraphicsBeginImageContext(myView.bounds.size);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Kelvin
A: 

May be this will help you (I am drawing a UIImage from context and then saving it in this tutorial):

http://www.gauravv.com/2010/01/01/core-graphics-tutorial-how-to-create-a-sleek-weatherview/

Gaurav Verma