首页 > 系统 > iOS > 正文

详解iOS App中图片的线段涂鸦功能的添加方法

2019-10-21 18:55:19
字体:
来源:转载
供稿:网友
这篇文章主要介绍了如何设计iOS App中图片的线段涂鸦功能,也就是很多应用中图片上传时带有的编辑功能的基础,需要的朋友可以参考下
 

接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线
创建项目 起名testAddLine

iOS,App,涂鸦

iOS,App,涂鸦

接下来我们在默认生成的ViewController中添加一张图片 待用
同时添加一个按钮 

复制代码代码如下:

- (void)viewDidLoad {  
    [super viewDidLoad];  
    // Do any additional setup after loading the view, typically from a nib.  
      
    UIImageView *imageV = [[UIImageView alloc]initWithFrame:CGRectMake(10, 120, screen_Width-20, screen_Height-150)];  
    imageV.image = [UIImage imageNamed:@"640-960-1.jpg"];  
    [self.view addSubview:imageV];  
      
    UIButton *testBtn = [[UIButton alloc]initWithFrame:CGRectMake(screen_Width/2.0-60, 60, 120, 36)];  
    [testBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  
    [testBtn setTitle:@"添加直线" forState:UIControlStateNormal];  
    [testBtn addTarget:self action:@selector(addLineAct:) forControlEvents:UIControlEventTouchUpInside];  
    [self.view addSubview:testBtn];  
}  
  
- (void)addLineAct:(id)sender{  
    NSLog(@"测试按钮");  
}  

接下来我们创建一个UIView 用来添加直线 起名:DrawLine

 

iOS,App,涂鸦

iOS,App,涂鸦

创建几个变量

复制代码代码如下:

@property(nonatomic,strong) NSMutableArray * completeLines; //已经画好的线条 存入数组  
@property(nonatomic,strong) NSMutableDictionary* LinesInProscess; //正在画的线条 存入字典  
@property(nonatomic,strong) UIColor *lineColor;//线条颜色  
@property (nonatomic)float lineWidth;//线条的粗细  

初始化DrawLine
复制代码代码如下:

//初始化  
- (id)initWithFrame:(CGRect)frame{  
    if (self = [super initWithFrame:frame]) {  
        //初始化变量  
        _completeLines = [[NSMutableArray alloc]init];  
        _LinesInProscess = [[NSMutableDictionary alloc]init];  
        //设置透明背景  
        self.backgroundColor = [UIColor clearColor];  
          
    }  
      
    return  self;  
}  

我们把线条单独抽象出来 创建一个类 创建对象 起名 Line

 

iOS,App,涂鸦

iOS,App,涂鸦

线条 两个属性 起始点 结束点(这就是数学中的两点确定一条直线) 
给Line 类创建两个属性

复制代码代码如下:

#import <Foundation/Foundation.h>  
#import <UIKit/UIKit.h>  
  
@interface Line : NSObject  
  
@property(nonatomic)CGPoint begin; //线条开始点  
  
@property(nonatomic)CGPoint end; //线条结束点  
  
@end  

接下来 我们重写DrawLine 的  drawRect 方法  绘制线条
复制代码代码如下:

// Only override drawRect: if you perform custom drawing.  
// An empty implementation adversely affects performance during animation.  
- (void)drawRect:(CGRect)rect {  
    // Drawing code  
      
    //获取上下文  
    CGContextRef cgt=UIGraphicsGetCurrentContext();  
    //设置线条宽度  
    CGContextSetLineWidth(cgt, self.lineWidth);  
    //设置线条两端形状为圆角  
    CGContextSetLineCap(cgt, kCGLineCapRound);  
      
    //设置颜色  
    [self.lineColor set];  
    //绘制已经完成的线段  
    for (Line *line in _completeLines){  
        CGContextMoveToPoint(cgt, [line begin].x, [line begin].y);  
        CGContextAddLineToPoint(cgt, [line end].x, [line end].y );  
        CGContextStrokePath(cgt);  
    }  
      
      
    //绘制正在画的线段  
    for (NSArray *v in _LinesInProscess) {  
        Line *line =[_LinesInProscess objectForKey:v];  
        CGContextMoveToPoint(cgt, [line begin].x, [line begin].y);  
        CGContextAddLineToPoint(cgt, [line end].x, [line end].y );  
        CGContextStrokePath(cgt);  
    }  
      
}  

实现几个手指滑动方法 用来接受手指的位置画线
复制代码代码如下:

//清空画板  
-(void)clearAll  
{  
    [_completeLines removeLastObject];  
    [_LinesInProscess removeAllObjects];  
    [self setNeedsDisplay];  
}  
  
  
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
{  
    //判断是否连按  
    for (UITouch *t in touches) {  
        if ([t tapCount]>1) {  
            //第二次画线时第一条线还未完成时结束画线  
            [self clearAll];  
            return;  
        }  
          
        //NSValue 作为键使用  
        NSValue *key=[NSValue valueWithNonretainedObject:t];  
          
        // 根据触摸位置创建Line对象  
        CGPoint loc=[t locationInView:self];  
        Line *newLine=[[Line alloc]init ];  
        newLine.begin=loc;  
        newLine.end=loc;  
        //将当前正在画的线存入字典  
        [_LinesInProscess setObject:newLine forKey:key];  
          
    }  
}  
  
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event  
{  
    //手指移动过程中按照当前手指的位置动态更新线条  
    for (UITouch * t in touches) {  
        NSValue *key=[NSValue valueWithNonretainedObject:t];  
        // 找对象当前UITouch对象的Line对象  
        Line *line =[_LinesInProscess objectForKey:key];  
          
        CGPoint loc=[t locationInView:self];  
        line.end=loc;  
    }  
    [self setNeedsDisplay];  
}  
  
-(void)endTouches:(NSSet *) touches  
{  
    //画线完成之后将当前线条加入_completeLines 数组中 同时删除字典_LinesInProscess里的线条  
    for (UITouch *t in touches) {  
        NSValue *key=[NSValue valueWithNonretainedObject:t];  
        Line *line =[_LinesInProscess objectForKey:key];  
        if (line) {  
            [_completeLines addObject:line];  
            [_LinesInProscess removeObjectForKey:key];  
        }  
    }  
    [self setNeedsDisplay];  
}  
  
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event  
{  
    [self endTouches:touches];  
}  
  
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
{  
    [self endTouches:touches];  
}  

 

回到 ViewController中 给按钮点击事件中 添加DrawLine到ImageView上

复制代码代码如下:

- (void)addLineAct:(id)sender{  
    NSLog(@"测试按钮");  
      
    DrawLine *touchdrawView = [[DrawLine alloc]initWithFrame:imageV.frame];  
  
    touchdrawView.lineColor = [UIColor yellowColor];  
    touchdrawView.lineWidth = 5.0;  
    touchdrawView.tag = 902;  
    [self.view addSubview:touchdrawView];  
      
      
}  

好了 运行程序试试
点击 添加直线 按钮之后 试试在图片上画线

 

iOS,App,涂鸦

 

带剪头的线条
在上面例子的基础上稍微拓展一下,给线段末尾加上一个箭头
给DrawLine 类中添的方法 drawRect 中添加一段代码

iOS,App,涂鸦

 

复制代码代码如下:

//添加剪头  
double r = sqrt((line.end.x-line.begin.x)*(line.end.x-line.begin.x)+(line.begin.y-line.end.y)*(line.begin.y-line.end.y));//线条长度  
CGContextMoveToPoint(cgt,line.end.x,line.end.y);  
//P1  
CGContextAddLineToPoint(cgt,line.end.x-(10*(line.begin.y-line.end.y)/r),line.end.y-(10*(line.end.x-line.begin.x)/r));  
//P3  
CGContextAddLineToPoint(cgt,line.end.x+(20*(line.end.x-line.begin.x)/r), line.end.y-(20*(line.begin.y-line.end.y)/r));  
//P2  
CGContextAddLineToPoint(cgt,line.end.x+(10*(line.begin.y-line.end.y)/r),line.end.y+(10*(line.end.x-line.begin.x)/r));  
  
CGContextAddLineToPoint(cgt, line.end.x,line.end.y);  
CGContextDrawPath(cgt,kCGPathFillStroke);  
CGContextStrokePath(cgt);  

以上方法的思路 就是在线段画完之后 确定三个点 画一个三角形作为箭头形状

 

iOS,App,涂鸦



注:相关教程知识阅读请移步到IOS开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表