【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 ...
随机推荐
- 洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)
洛谷题目传送门 AC自动机入门--yyb巨佬的博客 AC自动机入手经典好题(虽然年代久远) 有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fa ...
- 云计算之路-阿里云上:服务器CPU 100%问题是memcached的连接数限制引起的
非常抱歉,昨天的服务器CPU 100%问题是达到 memcached 的连接数限制引起的,不是阿里云服务器的问题. 之前我们用的是阿里云“云数据库 memcached 版”,上个周末我们换成了自己搭建 ...
- vue.js 视频播放
最近心学习vue.js开发,video开发播放! 使用第三方的封装:https://www.npmjs.com/package/vue-video-player: 1. npm install vue ...
- gradle build docker image
前言:其实gradle-docker插件干的事和我们手动制作镜像是一样的,只不过它封装了一些步骤而已. eg:如果我们要将项目打包成镜像,首先我们要写Dockerfile,这是制作镜像的不可或缺的第一 ...
- Canvas 画布组件(官网翻译)
Canvas画布 The Canvas is the area that all UI elements should be inside. The Canvas is a Game Object w ...
- aspnetcore.webapi实践k8s健康探测机制 - kubernetes
1.浅析k8s两种健康检查机制 Liveness k8s通过liveness来探测微服务的存活性,判断什么时候该重启容器实现自愈.比如访问 Web 服务器时显示 500 内部错误,可能是系统超载,也可 ...
- UnderScore.jsAPI记录
Collection Functions (Arrays or Objects) each _.each(list, iterator, [context]) 遍历list中的所有元素 ...
- 用js写的时钟Demo
css代码: <style type="text/css"> .a { width: 200px; height: 100px; position: absolute; ...
- 笔记:MyBatis XML配置详解
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配置 properties ...
- 前端的UI设计与交互之反馈示篇
为了帮助用户了解应用当前要做什么,也给用户的下一步行为做参考,以及了解操作后所产生的结果 ,当用户和系统需要交互时,使用不同的模式来反馈信息或结果.当设计者使用反馈或者自定义一些反馈时,请注意:为用户 ...