这三种东西: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. Node.js Web框架收集

    原文地址:http://geek.csdn.net/news/detail/4020 框架列表: http://nodeframework.com/ 与其他很多语言一样,Node.js也有很多Web框 ...

  2. 在Asp.net MVC中使用Authorization Manager (AzMan)进行Windows用户身份认证

    背景 创建需要通过Windows用户进行身份认证的Asp.net MVC应用 要点 在Asp.net MVC应用基于Windows用户进行身份认证的方法有很多,如MVC自带的Windows认证就经常被 ...

  3. Head First HTML CSS XHTML笔记

    最近在看点前端的东西,看到了这本入门级的好书 <head></head>中的title和style <q></q> inline元素 在<p> ...

  4. Effective Java 26 Favor generic types

    Use generic types to replace the object declaration Add one or more type parameters to its declarati ...

  5. Spring中Template模式与callback的结合使用浅析

    Spring不论是与ibatis,还是与Hibernate的结合中,都使用到了Template模式与callback技术,来达到简化代码实现的目的.Template模式也即模板模式,用于对一些不太变化 ...

  6. 集线器hub、交换机switch、路由器router 的区别

    原文链接:http://blog.csdn.net/thq0201/article/details/7782319 首先说HUB,也就是集线器.它的作用可以简单的理解为将一些机器连接起来组成一个局域网 ...

  7. HTML实体对照表

    HTML开发特殊字符是没办法原样输出的,必须用到实体,为了以后查看方便,收藏一下实体对照表是必要的,另外,使用<xmp></xmp>标签可以原样输出,当然,也包括特殊字符啦! ...

  8. zoj 3229 Shoot the Bullet(无源汇上下界最大流)

    题目:Shoot the Bullet 收藏:http://www.tuicool.com/articles/QRr2Qb 把每一天看成一个点,每个女孩也看成一个点,增加源和汇s.t,源向每一天连上[ ...

  9. JavaScript的执行上下文

    在JavaScript的运行过程中,经常会遇到一些"奇怪"的行为,不理解为什么JavaScript会这么工作. 这时候可能就需要了解一下JavaScript执行过程中的相关内容了. ...

  10. TFS 2013”无法移除仍为团队管理员身份的标识”

    由于开发人员的工作变动,在TFS 2013的日常维护中,经常需要将已经离开团队的成员账户移除出本团队项目. 一.将用户从团队成员中移除 一般情况下,只需要在团队项目的控制面板界面(控制面板>Co ...