这三种东西:CGContextRefCGPathUIBezierPath。本质上都是一样的,都是使用Quartz来绘画。只不过把绘图操作暴露在不同的API层面上,在具体实现上,当然也会有一些细小的差别。

我们将主要使用这3个类型,绘制出同一张图片,如下,一个笑脸:

首先使用Quartz的CGPath来做这张图。很简单,首先创建用于转移坐标的Transform,然后创建一个CGMutablePathRef(属于CGPath类型)对象。接着通过两个CGPathAddEllipseInRect和一个CGPathAddArc函数来绘制Path中的两个眼睛和一个嘴,注意把CGAffineTransform的地址传进去,这样Transform才会应用。接着把这个创建好的CGPath加入到当前CGContextRef中,最后通过CGContextRef执行绘画。

代码:

- (void)viewDidLoad{    [super viewDidLoad];

    //开始图像绘图    UIGraphicsBeginImageContext(self.view.bounds.size);    //获取当前CGContextRef    CGContextRef gc = UIGraphicsGetCurrentContext();

    //创建用于转移坐标的Transform,这样我们不用按照实际显示做坐标计算    CGAffineTransform transform = CGAffineTransformMakeTranslation(50, 50);    //创建CGMutablePathRef    CGMutablePathRef path = CGPathCreateMutable();    //左眼    CGPathAddEllipseInRect(path, &transform, CGRectMake(0, 0, 20, 20));    //右眼    CGPathAddEllipseInRect(path, &transform, CGRectMake(80, 0, 20, 20));    //笑    CGPathMoveToPoint(path, &transform, 100, 50);    CGPathAddArc(path, &transform, 50, 50, 50, 0, M_PI, NO);    //将CGMutablePathRef添加到当前Context内    CGContextAddPath(gc, path);    //设置绘图属性    [[UIColor blueColor] setStroke];    CGContextSetLineWidth(gc, 2);    //执行绘画    CGContextStrokePath(gc);

    //从Context中获取图像,并显示在界面上    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();

    UIImageView *imgView = [[UIImageView alloc] initWithImage:img];    [self.view addSubview:imgView];}

接下来,我们不去使用CGPath类型的相关函数,而完全使用CGContextRef相关的函数,这些函数执行起来其实是和上面讲的的CGPath完全等价的。

这里需要注意的是,完全使用CGContextRef的话,Transform的应用需使用CGContextTranslateCTM函数。

完整代码:

- (void)viewDidLoad{    [super viewDidLoad];

    //开始图像绘图    UIGraphicsBeginImageContext(self.view.bounds.size);    //获取当前CGContextRef    CGContextRef gc = UIGraphicsGetCurrentContext();

    //使用CGContextTranslateCTM函数来转移坐标的Transform,这样我们不用按照实际显示做坐标计算    CGContextTranslateCTM(gc, 50, 50);    //左眼    CGContextAddEllipseInRect(gc, CGRectMake(0, 0, 20, 20));    //右眼    CGContextAddEllipseInRect(gc, CGRectMake(80, 0, 20, 20));    //笑    CGContextMoveToPoint(gc, 100, 50);    CGContextAddArc(gc, 50, 50, 50, 0, M_PI, NO);    //设置绘图属性    [[UIColor blueColor] setStroke];    CGContextSetLineWidth(gc, 2);    //执行绘画    CGContextStrokePath(gc);

    //从Context中获取图像,并显示在界面上    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    UIImageView *imgView = [[UIImageView alloc] initWithImage:img];    [self.view addSubview:imgView];}

同样会绘制出上面的图形。

最后我们使用UIBezierPath类型来完成上述图形,UIBezierPath很有意思,它包装了Quartz的相关API,自己存在于UIKit中,因此不是基于C的API,而是基于Objective-C对象的。那么一个非常重要的点是由于离开了Quartz绘图,所以不需要考虑Y轴翻转的问题,在画弧的时候,clockwise参数是和现实一样的,如果需要顺时针就传YES,而不是像Quartz环境下传NO的。

其次椭圆的创建需使用bezierPathWithOvalInRect方法,这里名字是Oral而不是Quartz中的Ellipse

最后注意UIBezierPathapplyTransform方法需要最后调用。

完整代码:

- (void)viewDidLoad{    [super viewDidLoad];

    //开始图像绘图    UIGraphicsBeginImageContext(self.view.bounds.size);

    //创建UIBezierPath    UIBezierPath *path = [UIBezierPath bezierPath];    //左眼    [path appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 20, 20)]];    //右眼    [path appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(80, 0, 20, 20)]];    //笑    [path moveToPoint:CGPointMake(100, 50)];    //注意这里clockwise参数是YES而不是NO,因为这里不知Quartz,不需要考虑Y轴翻转的问题    [path addArcWithCenter:CGPointMake(50, 50) radius:50 startAngle:0 endAngle:M_PI clockwise:YES];    //使用applyTransform函数来转移坐标的Transform,这样我们不用按照实际显示做坐标计算    [path applyTransform:CGAffineTransformMakeTranslation(50, 50)];    //设置绘画属性    [[UIColor blueColor] setStroke];    [path setLineWidth:2];    //执行绘画    [path stroke];

    //从Context中获取图像,并显示在界面上    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    UIImageView *imgView = [[UIImageView alloc] initWithImage:img];    [self.view addSubview:imgView];

iOS: 使用CGContextRef,CGPath和UIBezierPath来绘画的更多相关文章

  1. [ios]ios画线 使用CGContextRef,CGPath和UIBezierPath来绘画

    参考 :http://www.mgenware.com/blog/?p=493 这三种东西:CGContextRef,CGPath和UIBezierPath.本质上都是一样的,都是使用Quartz来绘 ...

  2. iOS使用Core Graphics和UIBezierPath绘画

    通过UIView的子类的- (void)drawRect:(CGRect)rect 函数可用对视图进行重新绘画: 要重新绘画可以通过Core Graphics和UIBezierPath来实现. 1.通 ...

  3. IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

    ... 首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Con ...

  4. (转) IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

    首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ...

  5. [置顶] IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)

    首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ...

  6. iOS绘图CGContextRef详解

    转自:http://blog.csdn.net/u014286994/article/details/51333118 /* CoreGraphics - CGContext.h */ /** Gra ...

  7. OS: 剪裁UIImage部分不规则区域

    首先,我们需要把图片展示在界面上.很简单的操作,唯一需要注意的是由于CGContextDrawImage会使用Quartz内以左下角为(0,0)点的坐标系,所以需要使用CGContextTransla ...

  8. iOS 之UIBezierPath

    代码地址如下:http://www.demodashi.com/demo/11602.html 在之前的文章中,由于用到过UIBezierPath这个类,所以这里就对这个类进行简单的记录一下,方便自己 ...

  9. iOS旋钮动画-CircleKnob

    欢迎相同喜欢动效的project师/UI设计师/产品添加我们 iOS动效特攻队–>QQ群:547897182 iOS动效特攻队–>熊熊:648070256 前段时间和群里的一个设计师配合. ...

随机推荐

  1. Android中有时候运行程序的时候会报错:An internal error occurred during:。。。。

    解决办法: Project -> Properties -> Run/Debug Settings: 1. select "Launching New_configuration ...

  2. swipe js dynamic content

    swipe js dynamic content swipe 动态改变内容时,需要用 update 一下. swiper.update(true); 实例: HTML Code  页面用的FreeMa ...

  3. (转)Block的使用

    转:http://my.oschina.net/leejan97/blog/268536 本文翻译自苹果的文档,有删减,也有添加自己的理解部分. 如果有Block语法不懂的,可以参考fuckingbl ...

  4. Oracle查看所有用户

    1.查看所有用户:select * from dba_users;   select * from all_users;   select * from user_users; 2.查看用户或角色系统 ...

  5. 用C#实现RSS的生成和解析,支持RSS2.0和Atom格式

    RSS已经非常流行了,几乎所有有点名气的和没名气的网站都有提供RSS服务. 本文详细教你什么是RSS,如是在.Net中使用RSS. 1.那么什么是RSS呢? RSS是一种消息来源格式规范,用以发布经常 ...

  6. CentOS下安装MySQL

    首先通过网络链接的方式在线安装上mysql服务器端吧!(备注:我开始登录服务器的时候是用的其他用户而不是超级管理员,所以安装MySQL的时候需要切换到超级管理员才可以实现软件的正确安装.命令则是:su ...

  7. IIS does not list a website that matches the launch url

    233down voteaccepted I hate answering my questions: in my question i stated that i was running VS un ...

  8. oracle序列

    一.序列 序列是oracle用来生产一组等间隔的数值.序列是递增,而且连续的.oracle主键没有自增类型,所以一般使用序列产生的值作为某张表的主键,实现主键自增.序列的编号不是在插入记录的时候自动生 ...

  9. 谈谈Java的集合组件

    让我们一起谈谈Java的集合组件 我们在使用Java的时候,都会遇到并使用到Java的集合.在这里通过自己的理解和网上的资源对Java的集合方面的使用做一个简单的讲解和总结. Java主要分为3个集合 ...

  10. sql server 2005 32位+64位、企业版+标准版、CD+DVD 下载地址大全 .

    企业版DVD SQL Server 2005 Enterprise Edition(支持超大型企业) 32 位DVD: ed2k://|file|cs_sql_2005_ent_x86_dvd.iso ...