iOS 图像编辑开源库 - 或者只是一些技巧

发布于 2024-11-16 23:28:07 字数 720 浏览 2 评论 0原文

对于我正在编写的 iOS 应用程序,我想从照片库中拍摄一张照片,然后让用户“清理它”,本质上是删除其中不需要的部分。例如,假设用户选择一个人的照片,我的应用程序只需要头部,其他所有内容都应该删除,因此用户需要通过删除背景、身体或照片中的其他人来清理照片。想象一下类似 Photoshop 的体验,但只有一个工具 - 橡皮擦。

我正在寻找开源库、示例或只是如何开始使用的提示。

我知道如何使用 UIImagePickerController 来选择图像,因此缺少的部分是实际的编辑。作为一个完全的菜鸟,我很乐意就合理的方法获得一些建议,最好是一些示例代码,甚至是可重用的库。

我想,在高层次上,我想要做的是从一个矩形图像开始,并确保它有一个 alpha 层,然后当用户触摸图像的某些部分以删除它们时,我需要从中“删除”更多像素通过将 alpha 级别更改为 0 来更改图像。但这是一个太高级的描述,我什至不确定它是否正确......另一个合理的要求是撤消支持。

我想到的另一种方法是使用原始图像和用户在触摸屏幕时编辑的蒙版图像,当“完成”时,以某种方式将两个图像编译为带有 Alpha 的一个图像。当然,这是一个实现细节,用户不需要知道屏幕上有两个图像。

如果可能的话,我想停留在 UIImage 或 UIImageView 或 Core Graphics 级别,而不必与 OpenGL ES 发生冲突。我的直觉是,更高的图形级别应该具有足够的性能并且易于理解,可维护的干净代码是一个考虑因素......

任何建议都表示赞赏,谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羁绊已千年 2024-11-23 23:28:07

事实证明这非常简单,感谢@Rog 的指点。
我将在下面粘贴我的解决方案。这在控制器代码中:

#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];
  }
}

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];
  }
}
吃颗糖壮壮胆 2024-11-23 23:28:07

您需要熟悉 Quartz 2D / CoreGraphics。本指南对您来说是一个良好的开始 http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html

您所描述的任务可以像您想要的那样简单或复杂。从让用户用手指拖动手指来擦除照片周围的区域(简单),到尝试检测高对比度区域以帮助您猜测要剪切的位置(相当复杂)。

如果您选择前者,您本质上会想要根据用户触摸创建一个剪切蒙版,因此请查看 UIView 的 TouchesBegan、touchesMoved 和 TouchesEnded 方法。

对于剪贴蒙版,这可能是一个很好的简单示例,可以帮助您入门如何擦除 UIImage 的一部分< /a>

祝你好运,这听起来是一个有趣的(如果不是具有挑战性的)项目。

You will need to get well acquainted with Quartz 2D / CoreGraphics. This guide is a good start for you http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html

The task you have described can be as simple or as complicated as you want. From letting the user use their fingers to erase the area around the photo by dragging their finger around (easy) to you trying to detect high contrast areas that help you guess where to cut (pretty complicated).

If you choose the former, you will essentially want to create a clipping mask based on user touches so have a look at the touchesBegan, touchesMoved and touchesEnded methods of UIView.

For the clipping mask, this is probably a good simple example to get you started How erase part of UIImage

Good luck with it, it sounds like a fun (if not challenging) project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文