iOS paint optimization - ios

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).

Related

CGcontext drawing on image not working

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.

having both scrolling and drawing

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.

Image gets scale on every touch end after drawing on it - iOS

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

drawing in the UIImageView moves up after every stroke

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.

drawing application for iOS performance issue

I'm creating drawing application for iOS. To draw something with a touch I used a code from this tutorial: http://www.raywenderlich.com/18840/how-to-make-a-simple-drawing-app-with-uikit
My code that I use for drawing is the following:
- (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 {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(self.view.frame.size);
[self.tempDrawImage.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);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:opacity];
UIGraphicsEndImageContext();
lastPoint = currentPoint;
NSLog(#"Moved");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(!mouseSwiped) {
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();
}
My problem is the following: this code works good on simulator and on my iPhone 5, but when I run it on my iPad 2, it's not working good. I mean when the touch is moved it gets drawn on the screen only each 3 seconds or something like this (it's not continous). Moreover when I keep moving my finger without lifting my finger app crashes after sometime.
I guess it's a performance issue. But why? Do you have any idea how can I fix it?
The problem is that you keep calling [self.tempDrawImage.image drawInRect:]. This call renders an image on the CPU and is extremely slow. You're unnecessarily beginning and ending the image context. Use this code instead, I tested it on an iPad 2 and it works smoothly.
- (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();
}
yes, but with this you will have a memory problem ... memory warning and crash.
if you want to try, draw between 50 and 150 lines, you can see how it causes memory problems.
if you want to fix this, in the method touchesEnded change it to this :
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UIGraphicsEndImageContext(); //<----this is correct
if(!mouseSwiped) {
//UIGraphicsEndImageContext(); <--- this is the issue
and then works perfect !!

Resources