1

Before Colouring the image:

enter image description here

After Colouring the Image:

enter image description here

This is my code :

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; touchPoint = [touch locationInView:self.imgColor]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)]; [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)]; startingPoint=touchPoint; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 3.0; shapeLayer.fillColor = [[UIColor redColor] CGColor]; [self.imgColor.layer addSublayer:shapeLayer]; [arrLayer addObject:shapeLayer]; NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y); } 

Depend upon the user touch, it's drawing a line inside UIImageView.

What i need is :

If image size is to small, then I don't like to allow draw outside the image.

Within the image user have to draw ,is there any way? Please suggest me.

6
  • Simplest way is stop the line when if (!CGRectContainsPoint(doggyImage.frame, touchPoint)) Commented Jan 11, 2016 at 11:40
  • ok @zcui93 i try your point ... Commented Jan 11, 2016 at 11:42
  • no @zcui93 my UIImageView frame is big ,but the dog image is small ,i like to color only inside the dog image . Commented Jan 11, 2016 at 11:44
  • The code suggested only prevent the line drawing from inside to outside. The idea is to check whether the touch point is inside your dog image or not. You need to do some similar check to not start drawing when touchStart. Commented Jan 11, 2016 at 11:48
  • can you suggest some more code deep about it @zcui93 Commented Jan 11, 2016 at 11:49

4 Answers 4

1

Add this code to your touch handing view.

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { return CGRectContainsPoint(doggyImage.frame, point) } 
Sign up to request clarification or add additional context in comments.

Comments

0

Code provided in the first comment if (!CGRectContainsPoint(doggyImage.frame, touchPoint)) is some condition that you can use to check whether the touch point is in one specific view, where I think you should use to compare with your dog image (I don't know which variable it is, so I used doggyImage. Maybe self.imgColor is the correct one or not).

And for simplest solution, you need to do at least two things

  • If touchesBegan outside the doggyImage, don't do anything, just return.
  • Prevent lines been draw from inside to outside, so use the same condition, and apply the same code you used in touchesEnd to handle something like stopDrawLine.

More advanced method would include computing the nearest point from the touch to the image if it's outside, and draw it on the edge.

BTW, currently in your touchesMoved, you created one new UIBezierPath every single touch point, resulting in hundreds of discrete small pieces of line. You may want to try to new a path when touchesBegan and addLineToPoint in touchesMoved. So that the whole line is in one path, and you can therefore offer freatures like "undo".

Comments

0

take one CGRect object Globally assign its value as follow

 CGRect imagerect = CGRectMake(imgColor.center.x - (imgColor.image.size.width/2 + imgColor.frame.origin.x), imgColor.center.y - (imgColor.image.size.height/2+ imgColor.frame.origin.y), imgColor.image.size.width, imgColor.image.size.height); 

now in touchesMoved method put one condition before drawing if( CGRectContainsPoint(imagerect, touchPoint))

so the method will be like

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; touchPoint = [touch locationInView:self.imgColor]; if( CGRectContainsPoint(imagerect, touchPoint)) { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)]; [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)]; startingPoint=touchPoint; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 3.0; shapeLayer.fillColor = [[UIColor redColor] CGColor]; [self.imgColor.layer addSublayer:shapeLayer]; [arrLayer addObject:shapeLayer]; NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y); } } 

4 Comments

jay thanks for the answer but your code only work for rectangular image not for all image ,in my case image should be differ .like circle ,rect,eclipse .
I have added new answer please check. i have not edited it because if someone want draw in rectangular image then they will use this code
@jey after add layer how can i create new edited image from it and save or send it.
@HardikVyas it's too old hope below code work for you ``` - (UIImage *) imageWithView:(UIView *)view { UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [[UIScreen mainScreen] scale]); if (_videoURL) { [view.layer renderInContext:UIGraphicsGetCurrentContext()]; } else { [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; } // UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; }``` you have to create image from your view
0

Might be this is not perfect solution but i try to make same as your requirements. please try with this

#import "ViewController.h" @interface ViewController () { CGPoint touchPoint,startingPoint; CALayer *layer; float x1; float y1; IBOutlet UIImageView *imgColor; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; layer = [CALayer layer]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -(void)viewDidAppear:(BOOL)animated { CGSize scaledImageSize = imgColor.image.size; CGRect imageFrame = CGRectMake(roundf(0.5f*(CGRectGetWidth(imgColor.bounds)-scaledImageSize.width)), roundf(0.5f*(CGRectGetHeight(imgColor.bounds)-scaledImageSize.height)), roundf(scaledImageSize.width), roundf(scaledImageSize.height)); x1 = imageFrame.origin.x ; y1 = imageFrame.origin.y ; } - (UIColor*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y { if (x < 0 || y<0 || x> image.size.width || y > image.size.height) { return nil; } // First get the image into your data buffer CGImageRef imageRef = [image CGImage]; NSUInteger width = CGImageGetWidth(imageRef); NSUInteger height = CGImageGetHeight(imageRef); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char)); NSUInteger bytesPerPixel = 4; NSUInteger bytesPerRow = bytesPerPixel * width; NSUInteger bitsPerComponent = 8; CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); CGContextRelease(context); // Now your rawData contains the image data in the RGBA8888 pixel format. NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel; CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f; CGFloat red = ((CGFloat) rawData[byteIndex] ) / alpha; CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha; CGFloat blue = ((CGFloat) rawData[byteIndex + 2] ) / alpha; byteIndex += bytesPerPixel; if (red >= 0 || green >= 0 || blue >= 0) { return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; } return nil; } -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; touchPoint = [touch locationInView:imgColor]; ; if ([self getRGBAsFromImage:imgColor.image atX:touchPoint.x - x1 andY:touchPoint.y - y1] && !(touchPoint.x == 0 && touchPoint.y == 0)) { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)]; [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)]; startingPoint=touchPoint; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 1.0; shapeLayer.fillColor = [[UIColor redColor] CGColor]; [imgColor.layer addSublayer:shapeLayer]; } } - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; { touchPoint = CGPointMake(0, 0); } @end 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.