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 前段时间和群里的一个设计师配合. ...
随机推荐
- Python 常用函数time.strftime()简介
time.strftime()可以用来获得当前时间,可以将时间格式化为字符串等等 格式命令列在下面:(区分大小写) %a 星期几的简写%A 星期几的全称%b 月分的简写%B 月份的全称%c 标准的 ...
- 测试mysql的sql语句预编译效果
玩Oracle的都比较关注shared pool,特别是library cache,在使用了绑定变量(预编译sql)之后确实能得到很大的性能提升.现在在转Mysql之后特别是innodb很多东西都还能 ...
- android适配器及监听点击和滚动在ListView中的使用
package com.example.demon08; import java.util.ArrayList;import java.util.HashMap;import java.util.Li ...
- Java API 快速速查宝典
Java API 快速速查宝典 作者:明日科技,陈丹丹,李银龙,王国辉 著 出版社:人民邮电出版社 出版时间:2012年5月 Java编程的最基本要素是方法.属性和事件,掌握这些要素,就掌握了解决实际 ...
- mysql大小写问题
以前做企业项目的时候,用的都是oracle数据库,在新公司项目用的是mysql,有关mysql大小写的问题 1 windows下默认mysql是不区分大小写的,要想让其支持大小写.更改方法 在my ...
- 由fdopen和fopen想到的
ISO C并没有规定fdopen,而是POSIX的补充. FILE *fopen(const char *path, const char *mode); FILE *fdopen(int fd, c ...
- java三篇博客转载 详解-vector,stack,queue,deque
博客一:转载自http://shmilyaw-hotmail-com.iteye.com/blog/1825171 java stack的详细实现分析 简介 我们最常用的数据结构之一大概就是stack ...
- 如何在ZBrush中添加毛发
ZBrush不仅能雕刻出完美的头发造型,还能够应用真实的头发和毛发.在制作毛发之前只需要简单定义遮罩区域,包括长短.疏密.当然,最重要的是,你可以使用Polypaint生成各种有色纤维,这将非常方便. ...
- HDU 1878 欧拉回路
并查集水题. 一个图存在欧拉回路的判断条件: 无向图存在欧拉回路的充要条件 一个无向图存在欧拉回路,当且仅当该图所有顶点度数都是偶数且该图是连通图. 有向图存在欧拉回路的充要条件 一个有向图存在欧拉回 ...
- [转]微服务(Microservice)那点事
WHAT – 什么是微服务 微服务简介 这次参加JavaOne2015最大的困难就是听Microservice相关的session,无论内容多么水,只要题目带microservice,必定报不上名,可 ...