ios基础篇(五)—— Quartz2D

一、Quartz2D

Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac OS X系统(跨平台,纯 C 语言的)。包含在 Core Graphics 框架中。

Quartz 2D能完成的工作

绘制图形 : 线条\三角形\矩形\圆\弧等

  • 绘制文字 微博图片上的水印
  • 绘制\生成图片(图像)
  • 读取\生成PDF
  • 截图\裁剪图片 方型图片->圆型 四个角是透明的
  • 自定义UI控件

注意:

  • Quartz2D 是苹果官方的二维绘图引擎,同时支持 iOS 和 Mac OS X 系统。
  • Cocos2D(Cocos2D-x、Cocos2D-iPhone、Cocos2D-HTML5等), Cocos2D 是一个第三方开源的2D游戏框架。做2D 游戏的 还有 Sprite Kit。 一般3D 游戏用 unity3D。

二、Quartz2D须知

  • Quartz2D的API是纯C语言的
  • Quartz2D的API来自于Core Graphics框架

  • 数据类型和函数基本都以CG作为前缀
  1. CGContextRef
  2. CGPathRef
  3. CGContextStrokePath(ctx);

三、Quartz2D实例

Quartz 2D能做很多强大的事情,例如

裁剪图片

涂鸦\画板

涂鸦\画板

报表:折线图\饼状图\柱状图 (查看 gif 动画图片)

自定义view(自定义UI控件)(通过 Quartz2D绘制自己的控件)

通过继承自 UIView,重写 drawRect:方法实现在控件上绘制各种内容

举例:

  • 通过继承自 UIView 实现自定义的 UIImageView
  • 实现自定义的“下载进度条”控件
  • 幸运转盘控件

四、Quartz2D 绘图主要步骤

  1. 获取【图形上下文】对象
  2. 向【图形上下文】对象中添加【路径】
  3. 渲染(把【图形上下文】中的图形会知道对应的设备上)

【图形上下文】= 草稿纸

  1. 获取草稿纸
  2. 向草稿纸画东西  画的东西约等于路径
  3. 按照草稿纸上的东西 画到自己真实想要画到的地方

五、图形上下文CGContextRef

  • 图形上下文(Graphics Context):是一个CGContextRef类型的数据
  • 图形上下文中主要包含如下信息
  • 绘图路径(各种各样的图形)
  • 绘图状态(颜色、线宽、样式、旋转、缩放、平移、图片裁剪区域等)
  • 输出目标(绘制到什么地方去?UIView、图片、pdf、打印机等) (输出目标可以是PDF文件、Bitmap或者显示器的窗口上)

  • 相同的一套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上 不同的上下文的类型,决定你的目标也不一样

Quartz2D提供了以下几种类型的Graphics Context:

  • Bitmap Graphics Context
  • PDF Graphics Context
  • Window Graphics Context
  • Layer Graphics Context(UI控件)
  • Printer Graphics Context

六、使用 Quartz2D 绘图

方式一:直接调用 Quartz2D 的 API 进行绘图

  • 代码量稍大
  • 功能全面
  • 步骤:

1> 获取绘图上下文

2> 把图形绘制到绘图上下文上

3> 把绘图上下文上的图形渲染到对应的设备上

方式二:调用 UIKit 框架封装好的 API 进行绘图

  • 代码相对简单
  • 只对部分 Quartz2D 的 API 做了封装
  • 对于没有封装的功能只能调用 Quartz2D 原生 API
  • 比如:画图片、文字到控件上。(UIKit 已经封装好了)

七、Quartz2D绘图的代码步骤

绘图方式一:

1. 获得图形上下文        C

CGContextRef ctx = UIGraphicsGetCurrentContext(); 

2. 拼接路径(下面代码是搞一条线段)

CGContextMoveToPoint(ctx, 10, 10); //起点
CGContextAddLineToPoint(ctx, 100, 100); //终点
CGContextAddLineToPoint(ctx, 150, 150); //连着的第三条线
//若需从其他起点开始画图 则继续 CGContextMoveToPoint

3. “渲染”(绘制路径)

CGContextStrokePath(ctx); // CGContextFillPath(ctx); 

StrokeXxxx 表示画线(边线)(空心图形)

FillXxx 表示画填充的图形(实心图形)

绘图方式二:

CGPathRef 路径对象   创建一个可变路径对象  C

绘图方式三:

C + OC   oc的path转换为c的path

绘图方式四:

C + OC   c的path转换为oc的path 第一条线用c画 第二条线用OC画

绘图方式五:

纯OC

在渲染时 是会自动获取上下文 并将路径放在上下文当中

 如何把c的转换为OC的      .CGpath

如何把oc的转换为C的 

UIBezierPath  类的 类方法 :bezierPathWithCGPath

七、使用路径对象绘制图形(更简单)

UIBezierPath对象

  • 1. 获取“图形上下文”对象
  • 2. 创建 UIBezierPath 对象
  • 3. 向 UIBezierPath 对象中绘制图形
  • 4. 把 UIBezierPath 对象添加到上下文中
  • 5. 把上下文对象渲染到设备上

注意: UIBezierPath 对象可以独立使用,  无需手动获取“图形上下文”对象

1.代码为什么要写在drawrect当中

因为在这个方法当中可以获取到正确的上下文(与上下文有关,先获取当前上下文,上下文是系统创建好的,在其他方法中,可能会获取不到)。

2.rect参数的含义

当前view的bounds (x y width height)    (rect参数是CGrect类型)

3.drawrect 什么时候调用

这个方法是系统调用

1.当这个view第一次显示的时候会调用

2.当这个view进程重绘的时候会调用

4.如何重绘

1.调用某个需要重绘的 view 对象的 setNeedsDisplay

2.调用某个需要重绘的 view 对象的 setNeedsDisplayInRect rect:参数表示需要重绘的区域 (重绘类似于tableview的刷新)

5.为什么不能手动调用 drawrect

手动调用的时候可能获取不到正确的上下文

调setNeedsDisplay 会自动调用drawrect

八、绘图顺序对最终结果的影响

九、在 UIView 上绘图

1. 获取与 UIView 相关的绘图上下文

  • 在drawRect:方法中取得的上下文

  • 在drawRect:方法中取得上下文后,就可以绘制东西到view上

View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了

View之所以能显示东西,完全是因为它内部的layer

十、drawRect:方法总结

  • 为什么要实现drawRect:方法才能绘图到view上?

因为在drawRect:方法中才能取得跟view相关联的图形上下文

  • drawRect:方法在什么时候被调用?

当view第一次显示到屏幕上时(加到UIWindow上显示出来)

重绘的时候:调用view的setNeedsDisplay或者setNeedsDisplayInRect:时

  • drawrect 什么时候调用

当 view 第一次被显示的时候调用(调用一次) -

重绘事件被触发的时候, 调用 -

    不要手动去调用这个方法, 否则可能无法正确的获取绘图上下文

  • 如何重绘

手动调用重绘方法 setNeedsDisplay 或者 setNeedsDisplayInRect:

  • rect参数的含义

参数 rect 表示当前 UIView 的 bounds

  • 为什么要在 - (void)drawRect:(CGRect)rect 方法中进行绘图

只有在这个方法中才能获取当前 View 的绘图上下文

十一、通过自定义view来演示案例

如何利用Quartz2D自定义view?(自定义UI控件)

如何利用Quartz2D绘制东西到view上?

  • 首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去
  • 其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面

自定义view的步骤

  • 新建一个类,继承自UIView
  • 实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中
  • 取得跟当前view相关联的图形上下文
  • 绘制相应的图形内容
  • 利用图形上下文将绘制的所有内容渲染显示到view上面

十二、绘制基本图形练习 

矩形

圆角矩形:

用圆角矩形画圆:当半径为宽度的一半 正好是圆

当cornerRadius大于50(宽度的一半)的2/3  都是圆

椭圆:

拿椭圆画成圆 将宽和高设置成一样即可

圆 用圆弧的方式画圆

起始位置为0 则为3点钟方向

OC 中:

    

 

C中:

c和oc 画弧线的区别:
相同参数 圆弧方向相反?

c中 顺时针 逆时针的方向相反

圆弧

示例:

换颜色:

c

 oc

可以混用

十三、几种不同的渲染方式

- 空心 StrokePath

- 实心 FillPath 和 EOFillPath (填充)

  • 填充一个路径的时候,路径里面的子路径都是独立填充的。
  • 假如是重叠的路径,决定一个点是否被填充,有两种规则
  • 1,nonzero winding number rule(非零绕数规则),假如一个点被从左到右跨过,计数器+1,从右到左跨过,计数器-1,最后,如果结果是0,那么不填充,如果是非零,那么填充
  • 2,even-odd rule(奇偶规则),假如一个点被跨过1次,被跨过了奇数次,那么要被填充,被跨过偶数次则不填充,和方向没有关系

c: 

oc:

even-odd rule:奇偶填充规则

被覆盖过奇数次的点填充,被覆盖过偶数次的点不填充

nonzero winding number rule:非零绕数规则

默认的填充规则,只需 KCGPathFill即可 从左往右跨过,+1 从右往左跨过 -1 最后如果为0 那么不填充 否则填充

1,表示先绘制的 2,表示后绘制的

两个圆心相同,半径不同的圆

射线 交点  奇数 填充     偶数 不填充

射线圆点的地方填充

addArcWithCenter 画圆弧函数

path.usesEvenOddFillRule = YES;  使用奇偶填充规则

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值