// // KKDrawTool.m // WWImageEdit // // Created by 邬维 on 2017/1/11. // Copyright © 2017年 kook. All rights reserved. // #import "KKDrawTool.h" @implementation KKDrawTool{ UIImageView *_drawingView; //画线view CGSize _originalImageSize; //初始大小 CGPoint _prevDraggingPosition; //拖动的起点 UIView *_menuView; //菜单栏 UISlider *_colorSlider; UISlider *_widthSlider; UIView *_strokePreview; UIView *_strokePreviewBackground; UIImageView *_eraserIcon; //橡皮擦 } #pragma -mark KKImageToolProtocol + (UIImage*)defaultIconImage{ return [UIImage imageNamed:@"ToolDraw"]; } + (NSString*)defaultTitle{ return Localized(@"JX_ImageEditDraw"); } + (NSUInteger)orderNum{ return KKToolIndexNumberSecond; } #pragma mark- implementation - (void)setup { _originalImageSize = self.editor.imageView.image.size; _drawingView = [[UIImageView alloc] initWithFrame:self.editor.imageView.bounds]; UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(drawingViewDidPan:)]; panGesture.maximumNumberOfTouches = 1; _drawingView.userInteractionEnabled = YES; [_drawingView addGestureRecognizer:panGesture]; [self.editor.imageView addSubview:_drawingView]; self.editor.imageView.userInteractionEnabled = YES; self.editor.scrollView.panGestureRecognizer.minimumNumberOfTouches = 2; self.editor.scrollView.panGestureRecognizer.delaysTouchesBegan = NO; self.editor.scrollView.pinchGestureRecognizer.delaysTouchesBegan = NO; _menuView = [[UIView alloc] initWithFrame:CGRectMake(self.editor.menuView.frame.origin.x, self.editor.view.height - 80, self.editor.menuView.frame.size.width, 80)]; _menuView.backgroundColor = self.editor.menuView.backgroundColor; [self.editor.view addSubview:_menuView]; [self setMenu]; _menuView.transform = CGAffineTransformMakeTranslation(0, self.editor.view.height-_menuView.top); [UIView animateWithDuration:kImageToolAnimationDuration animations:^{ _menuView.transform = CGAffineTransformIdentity; }]; } - (void)cleanup { [_drawingView removeFromSuperview]; self.editor.imageView.userInteractionEnabled = NO; self.editor.scrollView.panGestureRecognizer.minimumNumberOfTouches = 1; [UIView animateWithDuration:kImageToolAnimationDuration animations:^{ _menuView.transform = CGAffineTransformMakeTranslation(0, self.editor.view.height-_menuView.top); } completion:^(BOOL finished) { [_menuView removeFromSuperview]; }]; } - (void)executeWithCompletionBlock:(void (^)(UIImage *, NSError *, NSDictionary *))completionBlock { // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ UIImage *image = [self buildImage]; completionBlock(image, nil, nil); }); // }); } #pragma mark- other - (UISlider*)defaultSliderWithWidth:(CGFloat)width { UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, width, 34)]; [slider setMaximumTrackImage:[UIImage new] forState:UIControlStateNormal]; [slider setMinimumTrackImage:[UIImage new] forState:UIControlStateNormal]; [slider setThumbImage:[UIImage new] forState:UIControlStateNormal]; slider.thumbTintColor = [UIColor whiteColor]; return slider; } - (UIImage*)colorSliderBackground { CGSize size = _colorSlider.frame.size; UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); CGRect frame = CGRectMake(5, (size.height-10)/2, size.width-10, 5); CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:5].CGPath; CGContextAddPath(context, path); CGContextClip(context); CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGFloat components[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f }; size_t count = sizeof(components)/ (sizeof(CGFloat)* 4); CGFloat locations[] = {0.0f, 0.9/3.0, 1/3.0, 1.5/3.0, 2/3.0, 2.5/3.0, 1.0}; CGPoint startPoint = CGPointMake(5, 0); CGPoint endPoint = CGPointMake(size.width-5, 0); CGGradientRef gradientRef = CGGradientCreateWithColorComponents(colorSpaceRef, components, locations, count); CGContextDrawLinearGradient(context, gradientRef, startPoint, endPoint, kCGGradientDrawsAfterEndLocation); UIImage *tmp = UIGraphicsGetImageFromCurrentImageContext(); CGGradientRelease(gradientRef); CGColorSpaceRelease(colorSpaceRef); UIGraphicsEndImageContext(); return tmp; } - (UIImage*)widthSliderBackground { CGSize size = _widthSlider.frame.size; UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); UIColor *color = [[[KKImageEditorTheme theme] toolbarTextColor] colorWithAlphaComponent:0.5]; CGFloat strRadius = 1; CGFloat endRadius = size.height/2 * 0.6; CGPoint strPoint = CGPointMake(strRadius + 5, size.height/2 - 2); CGPoint endPoint = CGPointMake(size.width-endRadius - 1, strPoint.y); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddArc(path, NULL, strPoint.x, strPoint.y, strRadius, -M_PI/2, M_PI-M_PI/2, YES); CGPathAddLineToPoint(path, NULL, endPoint.x, endPoint.y + endRadius); CGPathAddArc(path, NULL, endPoint.x, endPoint.y, endRadius, M_PI/2, M_PI+M_PI/2, YES); CGPathAddLineToPoint(path, NULL, strPoint.x, strPoint.y - strRadius); CGPathCloseSubpath(path); CGContextAddPath(context, path); CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillPath(context); UIImage *tmp = UIGraphicsGetImageFromCurrentImageContext(); CGPathRelease(path); UIGraphicsEndImageContext(); return tmp; } - (UIColor*)colorForValue:(CGFloat)value { if(value<1/3.0){ return [UIColor colorWithWhite:value/0.3 alpha:1]; } return [UIColor colorWithHue:((value-1/3.0)/0.7)*2/3.0 saturation:1 brightness:1 alpha:1]; } - (void)setMenu { CGFloat W = 70; _colorSlider = [self defaultSliderWithWidth:_menuView.width - W - 20]; _colorSlider.left = 10; _colorSlider.top = 5; [_colorSlider addTarget:self action:@selector(colorSliderDidChange:) forControlEvents:UIControlEventValueChanged]; _colorSlider.backgroundColor = [UIColor colorWithPatternImage:[self colorSliderBackground]]; _colorSlider.value = 0; [_menuView addSubview:_colorSlider]; _widthSlider = [self defaultSliderWithWidth:_colorSlider.width]; _widthSlider.left = 10; _widthSlider.top = _colorSlider.bottom + 5; [_widthSlider addTarget:self action:@selector(widthSliderDidChange:) forControlEvents:UIControlEventValueChanged]; _widthSlider.value = 0.1; _widthSlider.backgroundColor = [UIColor colorWithPatternImage:[self widthSliderBackground]]; [_menuView addSubview:_widthSlider]; _strokePreview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, W - 5, W - 5)]; _strokePreview.layer.cornerRadius = _strokePreview.height/2; _strokePreview.layer.borderWidth = 1; _strokePreview.layer.borderColor = [[[KKImageEditorTheme theme] toolbarTextColor] CGColor]; _strokePreview.center = CGPointMake(_menuView.width-W/2, _menuView.height/2); [_menuView addSubview:_strokePreview]; _strokePreviewBackground = [[UIView alloc] initWithFrame:_strokePreview.frame]; _strokePreviewBackground.layer.cornerRadius = _strokePreviewBackground.height/2; _strokePreviewBackground.alpha = 0.3; [_strokePreviewBackground addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(strokePreviewDidTap:)]]; [_menuView insertSubview:_strokePreviewBackground aboveSubview:_strokePreview]; _eraserIcon = [[UIImageView alloc] initWithFrame:_strokePreview.frame]; _eraserIcon.image = [UIImage imageNamed:@"eraser"]; _eraserIcon.hidden = YES; [_menuView addSubview:_eraserIcon]; [self colorSliderDidChange:_colorSlider]; [self widthSliderDidChange:_widthSlider]; _menuView.clipsToBounds = NO; } - (void)colorSliderDidChange:(UISlider*)sender { if(_eraserIcon.hidden){ _strokePreview.backgroundColor = [self colorForValue:_colorSlider.value]; _strokePreviewBackground.backgroundColor = _strokePreview.backgroundColor; _colorSlider.thumbTintColor = _strokePreview.backgroundColor; } } - (void)widthSliderDidChange:(UISlider*)sender { CGFloat scale = MAX(0.05, _widthSlider.value); _strokePreview.transform = CGAffineTransformMakeScale(scale, scale); _strokePreview.layer.borderWidth = 2/scale; } - (void)strokePreviewDidTap:(UITapGestureRecognizer*)sender { _eraserIcon.hidden = !_eraserIcon.hidden; if(_eraserIcon.hidden){ [self colorSliderDidChange:_colorSlider]; } else{ _strokePreview.backgroundColor = [[KKImageEditorTheme theme] toolbarTextColor]; _strokePreviewBackground.backgroundColor = _strokePreview.backgroundColor; } } //监听手指移动 - (void)drawingViewDidPan:(UIPanGestureRecognizer*)sender { CGPoint currentDraggingPosition = [sender locationInView:_drawingView]; if(sender.state == UIGestureRecognizerStateBegan){ _prevDraggingPosition = currentDraggingPosition; } if(sender.state != UIGestureRecognizerStateEnded){ [self drawLine:_prevDraggingPosition to:currentDraggingPosition]; } _prevDraggingPosition = currentDraggingPosition; } //画线 -(void)drawLine:(CGPoint)from to:(CGPoint)to { CGSize size = _drawingView.frame.size; UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); [_drawingView.image drawAtPoint:CGPointZero]; CGFloat strokeWidth = MAX(1, _widthSlider.value * 65); UIColor *strokeColor = _strokePreview.backgroundColor; CGContextSetLineWidth(context, strokeWidth); CGContextSetStrokeColorWithColor(context, strokeColor.CGColor); CGContextSetLineCap(context, kCGLineCapRound); if(!_eraserIcon.hidden){ CGContextSetBlendMode(context, kCGBlendModeClear); } CGContextMoveToPoint(context, from.x, from.y); CGContextAddLineToPoint(context, to.x, to.y); CGContextStrokePath(context); _drawingView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } //生成修改后的图片 - (UIImage*)buildImage { UIGraphicsBeginImageContextWithOptions(_originalImageSize, NO, self.editor.imageView.image.scale); [self.editor.imageView.image drawAtPoint:CGPointZero]; [_drawingView.image drawInRect:CGRectMake(0, 0, _originalImageSize.width, _originalImageSize.height)]; UIImage *tmp = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return tmp; } @end