宣室求贤访逐臣,贾生才调更无伦。
可怜夜半虚前席,不问苍生问鬼神。
基本介绍
Quartz 2D
是一个二维绘图引擎,同时支持iOS和Mac系统Quartz 2D
能完成的工作- 绘制图形 : 线条\三角形\矩形\圆\弧等
- 绘制文字
- 绘制\生成图片(图像)
- 读取\生成PDF
- 截图\裁剪图片
- 自定义UI控件
- … …
drawRect
:方法的使用- 常见图形的绘制:线条、多边形、圆
- 绘图状态的设置:文字颜色、线宽等
- 图形上下文状态的保存与恢复(图形上下文栈)
- 图片裁剪
- 截图
图形上下文
- 图形上下文(
GraphicsContext
):是一个CGContextRef
类型的数据 图形上下文的作用:
- 保存绘图信息、绘图状态
- 决定绘制的输出目标(绘制到什么地方去?)(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)
相同的一套绘图序列,指定不同的GraphicsContext,就可将相同的图像绘制到不同的目标上
- Quartz2D提供了以下几种类型的Graphics Context:
1 | Bitmap Graphics Context |
如何利用Quartz2D自定义view?(自定义UI控件)
如何利用
Quartz2D
绘制东西到view上?- 首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去
- 其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面
为什么要实现
drawRect:
方法才能绘图到view上?- 因为在
drawRect:
方法中才能取得跟view相关联的图形上下文
- 因为在
drawRect:
方法在什么时候被调用?- 当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
调用view的setNeedsDisplay或者setNeedsDisplayInRect:时
- 当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
注意点
- Quartz2D的API是纯C语言的
- Quartz2D的API来自于Core Graphics框架
- 数据类型和函数基本都以CG作为前缀
1 | CGContextRef |
常用属性方法
drawRect:
中取得的上下文- 在
drawRect:
方法中取得上下文后,就可以绘制东西到view上 - View内部有个layer(图层)属性,drawRect:方法中取得的是一个
Layer GraphicsContext
,因此,绘制的东西其实是绘制到view的layer上去了 - View之所以能显示东西,完全是因为它内部的layer
- 在
自定义view的步骤
- 新建一个类,继承自UIView
- 实现
- (void)drawRect:(CGRect)rect
方法,然后在这个方法中 - 取得跟当前view相关联的图形上下文
- 绘制相应的图形内容
- 利用图形上下文将绘制的所有内容渲染显示到view上面
Quartz2D绘图
1 | // 这个方法只会在第一次加载的时候调用 不能的手动调用 |
重绘实现简单动画
CADisplayLink
定时器- 如果每隔一段时间重绘,一般不会使用NSTimer
- 每次屏幕刷新的时候才会触发,每秒屏幕刷新60次,即1秒触发60次
- 每次刷新的时候就重绘一次
setNeedsDisplay:
重绘,给当前控件绑定一个刷新的标识,每次屏幕刷新其实就是重绘- 每次屏幕自动刷新60次,每次刷新的时候只会把当前需要刷新的view重绘
1 | // 重绘(会删除上一次的绘制信息) |
1 | - (void)awakeFromNib |
常用拼接路径的函数
1 | // 新建一个起点 |
常用绘制路径的函数
1 | // Mode参数决定绘制的模式 |
图形上下文栈的操作
1 | // 将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”) |
矩阵操作
1 | // 利用矩阵操作,能让绘制到上下文中的所有路径一起发生变化 |
图片水印
- 有时候,在手机客户端app中也需要用到水印技术
- 比如,用户拍完照片后,可以在照片上打个水印,标识这个图片是属于哪个用户的
- 实现方式:利用
Quartz2D
,将水印(文字、LOGO)画到图片的右下角 - 核心代码
1 | 开启一个基于位图的图形上下文 |
图片裁剪
- 有时候需要把一张普通的图片刻意裁剪成圆形
1 | // 核心代码 |
屏幕截图
- 有时候需要截取屏幕上的某一块内容:
1 | // 核心代码 |
贝塞尔曲线应用
- 矩形
1 | UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(10, 10, 200, 200) cornerRadius:100]; |
- 椭圆
1 | UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 200, 200)]; |
- 圆弧
1 | // center:圆心 |
注意点
绘制图片的注意点
1 | // 绘制图片 |
绘制文字的注意点
1 | // 文字 |
内存管理
- 使用含有“
Create
”或“Copy
”的函数创建的对象,使用完后必须释放,否则将导致内存泄露 - 使用不含有“
Create
”或“Copy
”的函数获取的对象,则不需要释放 - 如果
retain
了一个对象,不再使用时,需要将其release
掉 - 可以使用
Quartz 2D
的函数来指定retain
和release
一个对象。例如,如果创建了一个CGColorSpace
对象,则使用函数CGColorSpaceRetain
和CGColorSpaceRelease
来retain和`release对象。 - 也可以使用
Core Foundation
的CFRetain和
CFRelease`。注意不能传递NULL值给这些函数
1 | // Create\copy\retain ---> release (出现这些关键字就需要手动管理内存) |
给UIImage添加分类
添加水印
分类的.h文件
1 |
|
分类的.m文件
1 |
|
使用
1 |
|
圆形切图
分类的.h文件
1 |
|
分类的.m文件
1 |
|
使用
1 |
|
截屏
分类的.h文件
1 |
|
分类的.m文件
1 |
|
使用
1 |
|