Crop image when draw line with hand - ios

I have a Image view added on a view. View is using UIBezierPath and touch responder methods for drawing line upon dragging on screen. Now I would like to clip the part of image that are below the line. How can I achieve this.
I use below methods to draw line
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p]; // (4)
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}

Try this:
#property (strong, nonatomic) UIBezierPath *bezierPath;
//...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
//...
self.bezierPath = [UIBezierPath bezierPath];
[self.bezierPath moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
//...
[self.bezierPath addLineToPoint:p];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
// Here you can call -croppedImage; method and get the image you need.
}
- (UIImage *)croppedImage
{
[self.bezierPath closePath];
UIImage *image = //Your initial image;
CGSize imageSize = image.size;
CGRect imageRect = CGRectMake(0, 0, imageSize.width, imageSize.height);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, [[UIScreen mainScreen] scale]);
// Create the clipping path and add it
[self.bezierPath addClip];
[image drawInRect:imageRect];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}
This is a fast written code, so can be possible mistakes. Sorry for that :)

Related

How to erase part of UIImageView with finger?

Basically I just want to make an eraser just like in Paint. I want to erase parts of a UIImageView just with my finger. I use the following code, however, it erases only with small strokes, while I want it to erase until I pull my finger off:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:bg];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGFloat brushSize = 35;
CGColorRef strokeColor = [UIColor clearColor].CGColor;
UITouch *touch = [touches anyObject];
currentTouch = [touch locationInView:bg];
UIGraphicsBeginImageContext(bg.frame.size);
CGContextRef context2 = UIGraphicsGetCurrentContext();
[bg.image drawInRect:CGRectMake(0, 0, bg.frame.size.width, bg.frame.size.height)];
CGContextSetLineCap(context2, kCGLineCapRound);
CGContextSetLineWidth(context2, brushSize);
CGContextSetStrokeColorWithColor(context2, strokeColor);
CGContextSetBlendMode(context2, kCGBlendModeClear);
CGContextBeginPath(context2);
CGContextMoveToPoint(context2, lastTouch.x, lastTouch.y);
CGContextAddLineToPoint(context2, currentTouch.x, currentTouch.y);
CGContextStrokePath(context2);
bg.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastTouch = currentTouch;
}
How should I change my code?

Slow performance on ipad erasing image

I have an iOS app that lets me erase an image with touch. It runs fine on iphone, but it lags a lot on ipad air. It uses ~40MB of memory on iphone, but ~200MB on ipad. Any ideas?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self.backImageView];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
currentTouch = [touch locationInView:self.backImageView];
CGPoint eraserPoint = CGPointMake(currentTouch.x - self.eraser.size.width/2, currentTouch.y - self.eraser.size.height/2);
self.backImageView.image = [self eraseImageAtPoint:eraserPoint inImageView:self.backImageView fromEraser:self.eraser];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (UIImage *)eraseImageAtPoint: (CGPoint)point inImageView: (UIImageView *)imgView fromEraser: (UIImage *)eraser {
UIGraphicsBeginImageContextWithOptions(imgView.frame.size, NO, 0.0f );
[imgView.image drawInRect:CGRectMake(0, 0, imgView.frame.size.width, imgView.frame.size.height)];
[eraser drawAtPoint:point blendMode:kCGBlendModeDestinationOut alpha:self.eraserSpeedSlider.value];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

How to allow users to draw throughout my app?

I have implemented the following code which allows the user to draw on an imageView. I would like to implement this throughout my app but would prefer not to keep copying and pasting.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
pointCurrent = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint pointNext = [touch locationInView:self.view];
UIGraphicsBeginImageContext(drawImage.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, 0.0, 1.0);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), pointCurrent.x, pointCurrent.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), pointNext.x, pointNext.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
pointCurrent = pointNext;
}
So far I have tried to create a category but I'm unsure if this is the right way to go about it. Do I make a custom method and try to call that in the other classes or am I barking up the wrong tree? Thanks in advance for taking the time to read this question.
I modified your code a little, because I was getting that same error that you mention in your comment. This code worked for me.
#interface RDImageView ()
#property (nonatomic) CGPoint pointCurrent;
#end
#implementation RDImageView
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
self.userInteractionEnabled = YES;
self.backgroundColor = [UIColor blueColor];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
self.pointCurrent = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint pointNext = [touch locationInView:self];
UIGraphicsBeginImageContext(self.frame.size);
[self.image drawInRect:self.bounds];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1,1, 0.0, 1.0);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.pointCurrent.x, self.pointCurrent.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), pointNext.x, pointNext.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.pointCurrent = pointNext;
}

Draw swipe with UIBezierPath in UIImageView

I am trying to draw something in UIImageView..I am able to draw without problems in UIView using the following code:
#implementation DrawView
{
UIBezierPath *path;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self setMultipleTouchEnabled:NO];
[self setBackgroundColor:[UIColor whiteColor]];
path = [UIBezierPath bezierPath];
[path setLineWidth:2.0];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[[UIColor blackColor] setStroke];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p]; // (4)
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
This skips imageview.. What I need is the opposite. I wanna draw in a uiimageview and skip uiview.. How can I do that? Thanks in advance..
The drawing surface needs to be a parent in the hierarchy of this view set. That way you can draw on the parent view, while the image lies underneath.
-Main View
--Drawing View
---UIImageView

IOS: draw a line with your finger

I want to know what's the approach to draw a line with a finger in a white view. I want to do an artboard, and I want begin to understand how draw a simple line or a track done with a finger. How can I do it?
I have understood your problem.
Please see the bellow code.It will use full for you.
-(void)intializeDrawImage
{
drawImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 100, 320, 320)];
[drawImage setBackgroundColor:[UIColor purpleColor]];
[drawImage setUserInteractionEnabled:YES];
[self.view addSubview:drawImage];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesBegan");
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:drawImage];
startPoint = p;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesMoved");
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:drawImage];
[self drawLineFrom:startPoint endPoint:p];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesEnded:touches withEvent:event];
}
-(void)drawLineFrom:(CGPoint)from endPoint:(CGPoint)to
{
drawImage.image = [UIImage imageNamed:#""];
UIGraphicsBeginImageContext(drawImage.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
[[UIColor greenColor] set];
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0f);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), from.x, from.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), to.x , to.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}

Resources