Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Image editing open source library - or just some tips

For an ios app I'm writing, I'd like to take an photo from the photo library and then let the user "clean it up", essentially deleting parts of it that are not needed. For example, suppose the user chooses a photo of a person, my app only needs the head and everything else should be deleted so the user needs to clean the photo up by deleting the background, the body or other persons in the photo. Imagine a photoshop like experience but with only one tool - the eraser.

I'm looking for open source libraries, or examples or just tips of how to get started with that.

I know how to use a UIImagePickerController to select an image so the missing part is the actual editing. As a complete noob I'd be happy to get some advice on what would be a reasonable approach to this, preferably with some sample code or even a reusable library.

I suppose, in a high level, what I want to do is start with a rectangular image and make sure it has an alpha layer and then as the user touches parts of the image to delete them, I need to "delete" more pixels from the image by changing their alpha level to 0. But that's a too high level description which I'm not even sure is correct... Another reasonable requirement is undo support.

Another approach that comes to mind is using the original image and a mask image which the user edits while touching the screen and when "done", somehow compile the two images to one image with alpha. Of course, this is an implementation detail and the user need not know that there are two images on the screen.

If possible, I'd like to stay at the UIImage or UIImageView or Core Graphics levels and not have to mess with OpenGL ES. My gut feeling is that the higher graphics levels should be performant enough and easy to understand, maintainable clean code is a consideration...

Any advice is appreciated, thanks!

like image 653
Ran Avatar asked Oct 11 '22 16:10

Ran


1 Answers

This turned out to be pretty easy, thanks for @Rog's pointers.
I'll paste my solution below. This goes in the controller code:

#pragma mark - touches

- (void) clipImageCircle:(CGPoint)point radius:(CGFloat)radius {
  UIBezierPath* uiBezierPath = [UIBezierPath  bezierPathWithArcCenter:point radius:radius startAngle:0 endAngle:2 * M_PI clockwise:NO];
  CGPathRef erasePath = uiBezierPath.CGPath;
  UIImage *img = imageView.image;
  CGSize s = img.size;
  UIGraphicsBeginImageContext(s);
  CGContextRef g = UIGraphicsGetCurrentContext();
  CGContextAddPath(g, erasePath);
  CGContextAddRect(g,CGRectMake(0, 0, s.width, s.height));
  CGContextEOClip(g);
  [img drawAtPoint:CGPointZero];
  imageView.image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
}

- (void) receiveTouch:(CGPoint)point {
  NSLog(@"%@", NSStringFromCGPoint(point));
  [self clipImageCircle:point radius:20];
}

- (void) endTouch {
  NSLog(@"END TOUCH");
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  // We currently support only single touch events
  UITouch* touch = [touches anyObject];
  CGPoint point = [touch locationInView:imageView];
  if ([imageView hitTest:point withEvent:event]) {
    [self receiveTouch:point];
  }
}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
  [self endTouch];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  [self endTouch];
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  UITouch* touch = [touches anyObject];
  CGPoint point = [touch locationInView:imageView];
  if ([imageView hitTest:point withEvent:event]) {
    [self receiveTouch:point];
  }
}
like image 87
Ran Avatar answered Nov 01 '22 19:11

Ran