【iOS】OC-Quartz2D简单使用
什么是Quartz2D
Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统
作用
|
1
2
3
4
5
6
7
8
9
|
<code>Quartz绘制图形绘制文字绘制生成图片(图像)读取生成PDF截图裁剪图片自定义UI控件…</code> |
Quartz2D在iOS开发中的价值
为了便于搭建美观的UI界面,iOS提供了UIKit框架,里面有各种各样的UI控件 UILabel:显示文字 UIImageView:显示图片
UIButton:同时显示图片和文字(能点击)
… …利用UIKit框架提供的控件,拼拼凑凑,能搭建和现实一些简单、常见的UI界面
但是,有些UI界面极其复杂、而且比较个性化,用普通的UI控件无法实现,这时可以利用Quartz2D技术将控件内部的结构画出来,自定义控件的样子 其实,iOS中大部分控件的内容都是通过Quartz2D画出来的,因此,Quartz2D在iOS开发中很重要的一个价值是:自定义view(自定义UI控件)
基本图形绘制
线段(线宽、线段样式、线条颜色)
|
1
2
3
|
<code>注意点:画线条只能通过空心样式画。CGContextStrokePath(ctx);</code> |
示例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<codeclass="hljs""">-(void)drawLine{ //1.获得图形上下文 CGContextRef //2.拼接图形(路径) //画一条直线 //设置起始位置 CGContextMoveToPoint(ctx,10,10); //添加一条线段到点(100,100) CGContextAddLineToPoint(ctx,100,100); //设置直线的宽度(黄色) //CGContextSetRGBStrokeColor(ctx, //set //stroke //fill [[UIColor //设置直线的宽度 CGContextSetLineWidth(ctx,10); //设置直线开头的样式(圆) CGContextSetLineCap(ctx, //设置直线转折点的样式(圆) CGContextSetLineJoin(ctx, //3.渲染显示到View上面 CGContextStrokePath(ctx);}</code> |
三角形
示例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<codeclass="hljs""">-(void)drawTriangle{ //1.获得图形上下文 CGContextRef //2.拼接图形(路径) //画一个三角形 //设置起始位置 CGContextMoveToPoint(ctx,0,0); //添加一条线段到点(100,100) CGContextAddLineToPoint(ctx,100,100); CGContextAddLineToPoint(ctx,120,20); CGContextClosePath(ctx); //设置直线的宽度(红色) [[UIColor //设置直线的宽度 CGContextSetLineWidth(ctx,10); //设置直线转折点的样式(切面) CGContextSetLineJoin(ctx, //3.渲染显示到View上面 CGContextStrokePath(ctx);}</code> |
矩形(空心、实心、颜色)
多种方法画矩形
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<codeclass="hljs""">// CGContextRef // CGContextMoveToPoint(ctx,10,10); CGContextAddLineToPoint(ctx,100,10); CGContextAddLineToPoint(ctx,100,100); CGContextAddLineToPoint(ctx,10,100); CGContextClosePath(ctx); //3.渲染 CGContextStrokePath(ctx);*方式二// CGContextRef// CGContextAddRect(ctx,10,10,100,100));//3.渲染 CGContextStrokePath(ctx);*// CGContextRef // CGContextStrokeRect(ctx,10,10,100,100)); * // CGContextRef // CGMutablePathRef CGPathAddRect(path,NULL,10,10,100,100)); // CGContextAddPath(ctx, CGPathRelease(path); // CGContextStrokePath(ctx); * UIBezierPath10,10,100,100)]; [path</code> |
椭圆圆圆弧饼状图
画圆弧方法说明:
|
1
2
3
4
5
6
7
8
9
|
<codeclass="hljs""">void CGContextRef CGFloat//圆心的x坐标 CGFloat//圆心的x坐标 CGFloat//圆的半径 CGFloat//开始弧度 CGFloat//结束弧度 int//0表示顺时针,1表示逆时针);</code> |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<codeclass="hljs""">-(void)drawCircle{ //1.获得图形上下文 CGContextRef //2.拼接图形 //画圆 CGContextAddEllipseInRect(ctx,50,50,100,100)); //设置宽度 CGContextSetLineWidth(ctx,10); //设置颜色 [[UIColor //3.渲染到View CGContextStrokePath(ctx);}</code> |
假如想创建一个完整的圆圈,那么开始弧度就是0 结束弧度是2pi
最后,函数执行完后,current point就被重置为(x,y).还有一点要注意的是,假如当前path已经存在一个subpath,
那么这个函数执行的另外一个效果是会有一条直线,从current point到弧的起点。
文字绘制和图片绘制(pattern)
<h4 id="绘制文字和图片不要使用<a href=" http:="" www.2cto.com="" kf="" ware="" c="" "="" target="_blank" class="keylink" style="color: rgb(51, 51, 51); font-family: 宋体; font-size: 14px;">c语言函数原因如下">绘制文字和图片不要使用C语言函数。原因如下:Quarz2D
绘图坐标系和 UIKit 坐标系不一致,导致使用 C 语言函数绘文字和图片就会出现文字和图片颠倒的现象,需要通过写代码调整,要利用到数学中矩阵的知识。 使用 C 语言函数绘制文字和图片代码复杂且函数不好理解。非常麻烦。
图形上下文(Graphics Context)
简介
图形上下文(Graphics Context):是一个CGContextRef类型的数据
图形上行下文的作用
保存绘图信息、绘图状态 决定绘制的输出目标(绘制到什么地方去?)
(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)

相同的一套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上

自定义View
如何利用Quartz2D绘制东西到view上?
首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去 其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面
自定义view的步骤
新建一个类,继承自UIView 实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中 取得跟当前view相关联的图形上下文 绘制相应的图形内容 利用图形上下文将绘制的所有内容渲染显示到view上面
drawRect:
为什么要实现drawRect:方法才能绘图到view上?
因为在drawRect:方法中才能取得跟view相关联的图形上下文
drawRect:方法在什么时候被调用?
当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
调用view的setNeedsDisplay或者setNeedsDisplayInRect:时
drawRect:中取得的上下文
在drawRect:方法中取得上下文后,就可以绘制东西到view上
View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了
View之所以能显示东西,完全是因为它内部的layer
绘图顺序

常用拼接路径函数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<codeclass="hljs""">新建一个起点void添加新的线段到某个点void添加一个矩形void添加一个椭圆void添加一个圆弧void CGFloatint |
常用绘制路径函数
|
1
2
3
4
5
6
7
8
9
10
11
|
<codeclass="hljs""">Mode参数决定绘制的模式void绘制空心路径void绘制实心路径void提示:一般以CGContextDraw、CGContextStroke、CGContextFill开头的函数,都是用来绘制路径的</code> |
图形上下文栈的操作
|
1
2
3
4
5
|
<codeclass="hljs""">将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”)void将栈顶的上下文出栈,替换掉当前的上下文void |
矩阵操作
利用矩阵操作,能让绘制到上下文中的所有路径一起发生变化
缩放
void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
旋转
void CGContextRotateCTM(CGContextRef c, CGFloat angle)
平移
void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)
Quartz2D的内存管理
使用含有“Create”或“Copy”的函数创建的对象,使用完后必须释放,否则将导致内存泄露
使用不含有“Create”或“Copy”的函数获取的对象,则不需要释放
如果retain了一个对象,不再使用时,需要将其release掉
可以使用Quartz 2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。
也可以使用Core Foundation的CFRetain和CFRelease。注意不能传递NULL值给这些函数
常用示例
图片水印
水印:在图片上加的防止他人盗图的半透明logo、文字、图标
水印的作用
告诉你这个图片从哪来的
主要是一些网站为了版权问题、广告而添加的
有时候,在手机客户端app中也需要用到水印技术
比如,用户拍完照片后,可以在照片上打个水印,标识这个图片是属于哪个用户的
实现方式:利用Quartz2D,将水印(文字、LOGO)画到图片的右下角
核心代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<codeclass="hljs""">#import@implementation+(instancetype)waterImageWithBg:(NSString{ UIImage@scene]; //1.创建一个基于位图的上下文(开启一个基于位图的上下文) //size: //opaque //scale //这段代码过后就相当于创建一个新的bitmap,也就是新的UImage对象 UIGraphicsBeginImageContextWithOptions(bgImage.size,0.0); //1.画背景 [bgImage0,0, //3.画右下角的水印 UIImage@logo]; CGFloat5; CGFloat0.5; CGFloat CGFloat CGFloat CGFloat [waterImage //4.从上下文取得制作完毕的UIImage对象 UIImage //5.结束上下文 UIGraphicsEndImageContext(); return}@end</code> |
可以将图片导出为png图片
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<codeclass="hljs"""> //6.显示到View self.iconView.image //7.将image压缩为PNG格式的二进制数据 NSData //8.写入文件 NSString@new.png]; [data // </code> |
图片裁剪
将普通的图片裁剪为圆形
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<codeclass="hljs"""> //1.获得图片 UIImage@abc]; //2.开始图片上下文 UIGraphicsBeginImageContext(image.size); //画圆 //这段代码获得的上下文就是上一段代码开始的上下文 CGContextRef CGContextAddEllipseInRect(ctx,0,0, CGContextClip(ctx); //3.绘制图片 [image //4.获得图片 UIImage self.iconView.image //5.关闭上下文 UIGraphicsEndImageContext();</code> |
截屏
截取屏幕上的内容
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<codeclass="hljs""">+(instancetype)catchImageWithView:(UIView{ //开启图形上下文 UIGraphicsBeginImageContext(view.frame.size); //将控制器中上下文的内容渲染到View中 [view.layer //从图形上下文获得图片 UIImage //关闭上下文 UIGraphicsEndImageContext(); return}</code> |
【iOS】OC-Quartz2D简单使用的更多相关文章
- 【iOS】Quartz2D简单介绍
一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图 ...
- iOS开发UI篇—Quartz2D简单使用(一)
iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: // // YYlineview.m // 03-画直线 // // Created by apple on 14-6-9. // ...
- iOS开发UI篇—Quartz2D简单使用(二)
iOS开发UI篇—Quartz2D简单使用(二) 一.画文字 代码: // // YYtextview.m // 04-写文字 // // Created by 孔医己 on 14-6-10. // ...
- iOS开发UI篇—Quartz2D简单使用(一)
iOS开发UI篇—Quartz2D简单使用(一) 一.画直线 代码: 1 // 2 // YYlineview.m 3 // 03-画直线 4 // 5 // Created by apple on ...
- iOS开发UI篇—Quartz2D简单介绍
iOS开发UI篇—Quartz2D简单介绍 一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\ ...
- iOS开发UI篇—Quartz2D简单使用(三)
iOS开发UI篇—Quartz2D简单使用(三) 一.通过slider控制圆的缩放 1.实现过程 新建一个项目,新建一个继承自UIview的类,并和storyboard中自定义的view进行关联. 界 ...
- AJ学IOS(28)UI之Quartz2D简单介绍
AJ分享,必须精品 iOS开发UI篇—Quartz2D简单介绍 什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : ...
- iOS - OC 面向对象语法
1.类 1)根类:因为类 NSObject 是层次结构的最顶层,因此称为根类. 可以将类称为子类(subclass)和父类(superclass),也可以将类称为子类和超类. 2)分类/类别(cate ...
- ios下最简单的正则,RegexKitLite
ios下最简单的正则,RegexKitLite 1.去RegexKitLite下载类库,解压出来会有一个例子包及2个文件,其实用到的就这2个文件,添加到工程中.备用地址:http://www.coco ...
- ios+oc面试题
ios+oc面试题 浅复制和深复制的区别?//浅拷贝和深拷贝答案:浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身.//通过对象的指针来访问这个对象深层复制(mutableCo ...
随机推荐
- Mybatis【逆向工程,缓存,代理】知识要点
前言 本文主要讲解Mybatis的以下知识点: Mybatis缓存 一级缓存 二级缓存 与Ehcache整合 Mapper代理 使用Mapper代理就不用写实现类了 逆向工程 自动生成代码 Mybat ...
- 【BZOJ1834】网络扩容(最大流,费用流)
[BZOJ1834]网络扩容(最大流,费用流) 题面 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下 ...
- 【HNOI2004】敲砖块(动态规划)
越来越懒了,不想粘题目 题解 样例的输入是个很好的提醒, 把他往左边对齐之后 如果要打掉某个位置,那么必须要打掉右上方的所有砖 然后就很明显的一个DP了.... #include<iostrea ...
- [BZOJ1009] [HNOI2008] GT考试 (KMP & dp & 矩阵乘法)
Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0< ...
- linux下主机用户管理(完整详情)
(一) 创建新用户 useradd命令(也可以使用adduser)用来创建新的用户帐号,其命令格式如下: 表4-19 useradd命令常用选项 常用现象意 义 -d设置新用户的登陆目录 -e设置新用 ...
- PAT乙级-1070. 结绳(25)
给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连.每次串连后,原来两段绳子的长度 ...
- 用python进行应用程序自动化测试(uiautomation)
本文主要用到一个uiautomation的开源框架,是一个咱们中国人写的,支持MFC,Windows Forms,WPF,Metro,Qt界面:此文主要是自己的个人总结,开源作者原文:http://w ...
- Linux乱码问题解决
语言设置常用命令 # echo $LANG # locale # LANG=zh_CN.UTF-8 # LANG=en Centos6中文语言包的设置 安装CentOS时选择了中文,但在终端不能显 ...
- Java设计模式(六)Adapter适配器模式
一.场景描述 “仪器数据采集器”包含采集数据以及发送数据给服务器两行为,则可定义“仪器数据采集器”接口,定义两方法“采集数据capture”和“发送数据sendData”. “PDF文件数据采集器”实 ...
- Linux系统-解压缩命令集合
Linux系统-解压缩命令集合 linux zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. ...