This is my code and it makes a very weird drawing when executed. Moreover image starts to disappear slowly by going down the imageview. Please help me with this
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
// if ([touch tapCount] == 2)
// {
// imageView.image = nil;
// }
location = [touch locationInView:touch.view];
lastClick = [NSDate date];
lastPoint = [touch locationInView:self.view];
lastPoint.y -= 0;
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{mouseSwiped = YES;
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(imageView.image.size);
[imageView.image drawInRect:CGRectMake(0, 44, imageView.image.size.width, imageView.image.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// lastPoint = currentPoint;
}
Moreover, the lines its drawing are of weird shape and they are disappearing continously
Your image is shifting, because you hardcoded offset in 44 points on each redraw.
Weird drawing is most likely the result of invalid coordinate system usage. You receive touch location in view coordinates, but draw in image coordinates. The easiest way to fix this issue is to create context with size, equal to view size instead of image size. Simply use imageView.bounds.size instead of imageView.image.size. Note that I assume you use "Scale to Fill" mode in your image view.
Whole drawing code after changes:
UIGraphicsBeginImageContext(self.imageView.bounds.size);
[self.imageView.image drawInRect:CGRectMake(0, 0, self.imageView.bounds.size.width, self.imageView.bounds.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.lastPoint.x, self.lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Also, your solution is not optimal in terms of performance. I suggest to draw path separately in view, instead of updating imageView image on each touch move.
Related
So, I am working on a virtual wall painting app.
I am able to draw some random lines by moving my finger on the image view(which has an image in it). Now I am trying to erase the drawings made on it without success as of yet.
I googled to find some solution and this line below came as full on recommended :-
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeClear);
Using this drawing can be erased,but it also erases the image on which the drawing are done. Is there any way to prevent the image from getting erased ? only erase the drawing made on it?
Following is the code I am using to erase the drawings :-
In touchesMoved:-
UITouch *touch = [touches anyObject];
CGPoint previousPoint = [touch locationInView:self.upperImageView];
UIGraphicsBeginImageContext(self.upperImageView.frame.size);
[self.upperImageView.image drawInRect:CGRectMake(0, 0, self.upperImageView.frame.size.width, self.upperImageView.frame.size.height)];
CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(),YES);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), eraserCap);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 45.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.25, 0.25, 0.25, 1.0);
CGMutablePathRef pathB = CGPathCreateMutable();
CGPathMoveToPoint(pathB,nil,location.x,location.y);
CGPathAddLineToPoint(pathB,nil,previousPoint.x,previousPoint.y);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextAddPath(UIGraphicsGetCurrentContext(),pathB);
CGContextStrokePath(UIGraphicsGetCurrentContext());
upperImageView.image = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
location = previousPoint;
and in touchesEnded:-
UITouch *touch = [touches anyObject];
CGPoint previousPoint = [touch locationInView:self.upperImageView];
UIGraphicsBeginImageContext(self.upperImageView.frame.size);
[self.upperImageView.image drawInRect:CGRectMake(0, 0, self.upperImageView.frame.size.width, self.upperImageView.frame.size.height)];
CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), YES);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), eraserCap);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0,1.0,1.0, 0.0);
CGMutablePathRef pathB = CGPathCreateMutable();
CGPathMoveToPoint(pathB, nil, location.x, location.y);
CGPathAddLineToPoint(pathB, nil, previousPoint.x, previousPoint.y);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextAddPath(UIGraphicsGetCurrentContext(),pathB);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.upperImageView.image = UIGraphicsGetImageFromCurrentImageContext();
// CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
previousPoint = location;
Is there anything I am doing wrong ? Please guide me in the right direction here, any help will be truly appreciated.
You can use different views for your image and drawings.
Or keep drawn paths in the array and delete each path separately.
Move all of your drawing to a separate UIView that overlays the UIImageView. That way, when you go to "clear" the contents, the original UIImageView is still completely intact underneath.
Something like this will get you set up:
- (void)viewWillAppear {
// Assumes you add a property of type UIView
self.drawingView = [[UIView alloc] initWithFrame:self.upperImageView.bounds];
[self.upperImageView addSubview:drawingView];
}
Then, your drawing code needs to only change to this (notice that you won't need to redraw the image any more):
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint previousPoint = [touch locationInView:self.drawingView];
UIGraphicsBeginImageContext(self.drawingView.frame.size);
CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(),YES);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), eraserCap);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 45.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.25, 0.25, 0.25, 1.0);
CGMutablePathRef pathB = CGPathCreateMutable();
CGPathMoveToPoint(pathB,nil,location.x,location.y);
CGPathAddLineToPoint(pathB,nil,previousPoint.x,previousPoint.y);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
CGContextAddPath(UIGraphicsGetCurrentContext(),pathB);
CGContextStrokePath(UIGraphicsGetCurrentContext());
upperImageView.image = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
location = previousPoint;
}
Make similar changes in the touchesEnded: method.
I created a drawing application. Since I use drawing on a large image I also need to have scrolling as well, but when I implemented scrolling, the drawing did not work any more.
I think there is a conflict on the touch event between drawing and scrolling.
I am thinking to do scrolling with two finger and drawing with one finger, but I could not find out how to implement it. I appreciate if any one could help me to fix this problem.
-(void)viewDidLayoutSubviews
{
scroller.scrollEnabled=YES;
scroller.contentSize=temp.frame.size;
toggledrawandscroll=false;
}
- (IBAction)changescrollstatues:(id)sender {
if(toggledrawandscroll){
//if draw is enable,disable it
toggledrawandscroll =false;
scroller.scrollEnabled=YES;
scroller.canCancelContentTouches=YES;
scroller.contentSize=temp.frame.size;
}
else{
toggledrawandscroll =true;
scroller.scrollEnabled=NO;
scroller.canCancelContentTouches=NO;
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
//initial setting for touch point
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
//set the concext
UIGraphicsBeginImageContext(self.view.frame.size);
[temp.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
//drawing setting
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(),red, green, blue, 1);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
temp.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(!mouseSwiped) {
//initial seting
UIGraphicsBeginImageContext(self.view.frame.size);
[temp.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
temp.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
}
So it looks like you have a toggle to enable scrolling? If that is the case your changesscrollstatues method never enables the scroll and never sets your boolean to YES. Your scroller is always enabled so the touch event won't get captured.
I am using this raywenderlich tutorial for the drawing on Image. That tutorial is with no image in background but here I want to draw on image from gallery.
So basically there are two UIImageView one is mainImage and tempDrawImage.
I am doing self.mainImage.image = randomImageFromGallery as a background image on which I want to draw
Now it shows up well n drawing also happens but the problem is image gets scale on every touch end.
Why the image keeps on scaling whats wrong with the code I am not doing anything on tempDrawImage where all the drawing happens ?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(self.view.frame.size);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(ctxt, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(ctxt, currentPoint.x, currentPoint.y);
CGContextSetLineCap(ctxt, kCGLineCapRound);
CGContextSetLineWidth(ctxt, brush );
CGContextSetRGBStrokeColor(ctxt, red, green, blue, 1.0);
CGContextSetBlendMode(ctxt,kCGBlendModeNormal);
CGContextStrokePath(ctxt);
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:opacity];
lastPoint = currentPoint;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
UIGraphicsEndImageContext();
if(!mouseSwiped)
{
self.tempDrawImage.image = nil;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(!mouseSwiped) {
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(self.view.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0];
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:opacity];
self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
self.tempDrawImage.image = nil;
UIGraphicsEndImageContext();
}
Check the size of the frames of all of the views you're using. Somewhere there is a mismatch so that one of the images your displaying is being scaled for display. Either the size the image is drawn at or the size it's displayed at needs to be changed.
If I understand well, you have a picture, and you want to draw up to this picture...
I propose :
set your tempDrawImage as inherited from UIView instead of UIImageView.
Store the points in an array while touches actions (touchesBegan, touchesMoved,...)
draw in the procedure (void)drawRect:(CGRect)rect
I am following the tutorial to create a simple drawing pad app (http://www.raywenderlich.com/18840/how-to-make-a-simple-drawing-app-with-uikit#comments)
The app has a single UIViewController and a UIImageView in it. After implementing touchBegin, touchMoved, and touchEnd, I could draw but after every stroke ends, the whole picture moves up. So after several strokes, the whole picture will be distorted and squeezed to the very top of the screen. Any suggestions? Thank you very much.
Here is the code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.mouseSwiped = NO;
UITouch *touch = [touches anyObject];
self.lastPoint =[touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
self.mouseSwiped = YES;
//find out the position where the touch event happened
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
//Setup the drawing context and prepare to draw something
UIGraphicsBeginImageContext(self.view.frame.size);
//Create a drawing area that is of the same size as the view dimensions
[self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
//Set the drawing starting point
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.lastPoint.x, self.lastPoint.y);
//Setup a line from the starting point to specified point, i.e current point in this case
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
//Set the drawing style
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), self.brush);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), self.red, self.green, self.blue, 1);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
//Paint the line
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.mainImage.image=UIGraphicsGetImageFromCurrentImageContext();
[self.mainImage setAlpha:self.opacity];
UIGraphicsEndImageContext();
self.lastPoint = currentPoint;
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if(!self.mouseSwiped){
UIGraphicsBeginImageContext(self.view.frame.size);
[self.mainImage.image drawInRect:
CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), self.brush);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(),
self.red, self.green, self.blue, self.opacity);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.lastPoint.x, self.lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.lastPoint.x, self.lastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:self.opacity];
self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
You probably have a mismatch between the size of the 2 views you're using, so as you move between the 2 different coordinate spaces you get a scaling effect.
Hi I am currently working on an app that contains taking notes by drawing. I followed ray wenderlich tutorials and as far I've got, I ended up with this code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = NO;
UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGFloat red,green,blue,alpha;
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.mainImage.frame.size.width, self.mainImage.frame.size.height)];
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),[self getBlendMode]);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x , lastPoint.y );
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x , currentPoint.y );
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), [self getBrushSize] );
[[self getPaintColor] getRed:&red green:&green blue:&blue alpha:&alpha];
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),[self getBlendMode]);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:[self getPaintAlpha]];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGFloat red,green,blue;
if(!mouseSwiped) {
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.mainImage.frame.size.width, self.mainImage.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), [self getBrushSize]);
[[self getPaintColor] getRed:&red green:&green blue:&blue alpha:nil];
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, [self getPaintAlpha]);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y - self.mainImage.frame.origin.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y - self.mainImage.frame.origin.y );
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
UIGraphicsBeginImageContext(self.mainImage.frame.size);
[self.mainImage.image drawInRect:CGRectMake(0, 0, self.mainImage.frame.size.width, self.mainImage.frame.size.height) blendMode:[self getBlendMode] alpha:1.0];
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.mainImage.frame.size.width, self.mainImage.frame.size.height) blendMode:[self getBlendMode] alpha:[self getPaintAlpha]];
if(self.drawMode != DrawEraser)
{
self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
self.tempDrawImage.image = nil;
}
UIGraphicsEndImageContext();
mouseSwiped = NO;
}
This code was working just fine with a small frame but when I increased the frame as 2 times bigger than before, unfortunately performance is not so good. So I was thinking about optimizing the code. I especially focused on touchesMoved method. As far as I understand, it draws the whole image on the context and changes it some and assigns the context to image. Drawing whole image seemed to be overload. So I was wondering, if I can draw some parts of the image to the context and do some changes and then draw this part of the context to the image.
you're right - redrawing the whole image every time in touchesMoved is a bad idea. I think you should create and keep a reference to the context at the beginning. In touches moved, you should draw on to that and create an image from the context. You can use CGBitmapContextCreate() to create the context instead of UIGraphicsBeginImageContext() and CGBitmapContextCreateImage() to create an image from the context instead of UIGraphicsGetImageFromCurrentImageContext(). Here is the documentation on how to use those (https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CGBitmapContext/Reference/reference.html).