服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - 详解iOS App中图片的线段涂鸦功能的添加方法

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

2021-01-13 16:14lwjok2007 IOS

这篇文章主要介绍了如何设计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关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28