iOS: 使用CGContextRef,CGPath和UIBezierPath来绘画
这三种东西:CGContextRef,CGPath和UIBezierPath。本质上都是一样的,都是使用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。
最后注意UIBezierPath的applyTransform方法需要最后调用。
完整代码:
- (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来绘画的更多相关文章
- [ios]ios画线 使用CGContextRef,CGPath和UIBezierPath来绘画
参考 :http://www.mgenware.com/blog/?p=493 这三种东西:CGContextRef,CGPath和UIBezierPath.本质上都是一样的,都是使用Quartz来绘 ...
- iOS使用Core Graphics和UIBezierPath绘画
通过UIView的子类的- (void)drawRect:(CGRect)rect 函数可用对视图进行重新绘画: 要重新绘画可以通过Core Graphics和UIBezierPath来实现. 1.通 ...
- IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
... 首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Con ...
- (转) IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ...
- [置顶] IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ...
- iOS绘图CGContextRef详解
转自:http://blog.csdn.net/u014286994/article/details/51333118 /* CoreGraphics - CGContext.h */ /** Gra ...
- OS: 剪裁UIImage部分不规则区域
首先,我们需要把图片展示在界面上.很简单的操作,唯一需要注意的是由于CGContextDrawImage会使用Quartz内以左下角为(0,0)点的坐标系,所以需要使用CGContextTransla ...
- iOS 之UIBezierPath
代码地址如下:http://www.demodashi.com/demo/11602.html 在之前的文章中,由于用到过UIBezierPath这个类,所以这里就对这个类进行简单的记录一下,方便自己 ...
- iOS旋钮动画-CircleKnob
欢迎相同喜欢动效的project师/UI设计师/产品添加我们 iOS动效特攻队–>QQ群:547897182 iOS动效特攻队–>熊熊:648070256 前段时间和群里的一个设计师配合. ...
随机推荐
- Node.js Web框架收集
原文地址:http://geek.csdn.net/news/detail/4020 框架列表: http://nodeframework.com/ 与其他很多语言一样,Node.js也有很多Web框 ...
- 在Asp.net MVC中使用Authorization Manager (AzMan)进行Windows用户身份认证
背景 创建需要通过Windows用户进行身份认证的Asp.net MVC应用 要点 在Asp.net MVC应用基于Windows用户进行身份认证的方法有很多,如MVC自带的Windows认证就经常被 ...
- Head First HTML CSS XHTML笔记
最近在看点前端的东西,看到了这本入门级的好书 <head></head>中的title和style <q></q> inline元素 在<p> ...
- Effective Java 26 Favor generic types
Use generic types to replace the object declaration Add one or more type parameters to its declarati ...
- Spring中Template模式与callback的结合使用浅析
Spring不论是与ibatis,还是与Hibernate的结合中,都使用到了Template模式与callback技术,来达到简化代码实现的目的.Template模式也即模板模式,用于对一些不太变化 ...
- 集线器hub、交换机switch、路由器router 的区别
原文链接:http://blog.csdn.net/thq0201/article/details/7782319 首先说HUB,也就是集线器.它的作用可以简单的理解为将一些机器连接起来组成一个局域网 ...
- HTML实体对照表
HTML开发特殊字符是没办法原样输出的,必须用到实体,为了以后查看方便,收藏一下实体对照表是必要的,另外,使用<xmp></xmp>标签可以原样输出,当然,也包括特殊字符啦! ...
- zoj 3229 Shoot the Bullet(无源汇上下界最大流)
题目:Shoot the Bullet 收藏:http://www.tuicool.com/articles/QRr2Qb 把每一天看成一个点,每个女孩也看成一个点,增加源和汇s.t,源向每一天连上[ ...
- JavaScript的执行上下文
在JavaScript的运行过程中,经常会遇到一些"奇怪"的行为,不理解为什么JavaScript会这么工作. 这时候可能就需要了解一下JavaScript执行过程中的相关内容了. ...
- TFS 2013”无法移除仍为团队管理员身份的标识”
由于开发人员的工作变动,在TFS 2013的日常维护中,经常需要将已经离开团队的成员账户移除出本团队项目. 一.将用户从团队成员中移除 一般情况下,只需要在团队项目的控制面板界面(控制面板>Co ...