本篇博客原文地址:http://blog.csdn.net/hello_hwc?viewmode=list

由于自己的项目需要,从网络上下载了许多关于绘制图形的demo,只是用在自己的项目中,很多地方的代码还是吃不透,于是决定仔细学习一下Quartz 2D这个强大的框架,这里也是站在别人的肩膀上来辅助自己的学习,感谢原博客的详细讲解。

Quartz 2D用来干嘛的?

Quartz 2D属于 Core Graphics (所以大多数方法以CG开头),是iOS/Mac OSX提供的在内核之上的强大的2D绘图引擎,并且这个绘图引擎是和设备无关的,也就是说,不用关心设备的大小,设备的分辨率,只要利用Quartz 2D,这些设备相关的就会自动处理。Quartz 2D能够提供的强大功能如下

透明层(transparency layers)

阴影

基于path的绘图(path-based drawing)

离屏渲染 (offscreen rendering)

复杂的颜色处理 (advanced color management)

抗锯齿渲染 (anti-aliased rendering)

PDF创建,展示,解析(这部分不在这个系列之中)

配合Core Animation, OpenGL ES,UIKit完成复杂的功能


画板 The Graphics Context

既然提到绘图,那自然有一个容器来包含绘制的结果,然后把这个结果渲染到屏幕上去,而Quartz 2D的容器就是CGContextRef数据模型。这种数据模型是C的结构体,存储了渲染到屏幕上的一切信息。

那么 最后Graphics Context 可以渲染到哪里呢?

Layer

Window

打印机

PDF

Bitmap(图片)


绘制模型

Quartz 2D采用painter’s model,意味着每一次绘制都是一层,然后按照顺序一层层的叠加到画板上。例如


数据类型

Quartz 2D中的数据类型都是透明的,也就是说用户只需要使用即可,不需要实际访问其中的变量。具体数据类型包括。

CGPathRef 路径类型,用来绘制路径(注意带有ref后缀的一般都是绘制的画板);

CGImageRef 绘制bitmap

CGLayerRef 绘制layer layer可复用 可离屏渲染

CGPatternRef 重复绘制

CGShadingRef和CGGradientref 绘制渐变(例如颜色渐变)

CGFunctionRef 定义回调函数,CGShadingRef和CGGradientRef辅助类型

CGColorRef 和 CGColorSpaceRef 定义如何处理颜色

CGFontRef 绘制文字


绘制状态

在使用Quartz 2D进行绘图的时候,经常需要设置颜色,字体,设置Context的坐标原点变换,context旋转。这些影响的都是当前绘制状态。Context利用堆栈的方式来保存绘制状态。调用CG ContextSaveGState来保存当前绘制状态的copy到堆栈中。利用CGContextRestoreGState弹出堆栈最顶层的绘制状态(取出来的都是最新的状态),设置为当前的绘制状态。注意,不是所有的参数都会保存,以下表格中的参数会保存


坐标系

和UIKit 的坐标系不一样,Quartz 2D的坐标系是在左下角的。

Quartz利用坐标系的旋转位移等操作来绘制复杂的动画。

但是有两个地方的坐标系是正常的UIKit坐标系

UIView 的context
通过这个方法UIGraphicsBeginImageContextWithOptions返回的context

一个简单的demo讲解:

新建一个UIView的子类,然后重写drawRect

- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
//返回当前的绘制容器
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);
//填充整个区域
CGContextFillRect(context, rect);
CGRect testRect = CGRectMake(, , , );
//在当前视图上绘制一个矩形
CGContextAddRect(context, testRect);
//给绘制的矩形填充颜色
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
//填充区域
CGContextFillRect(context, testRect);
}

然后,这样调用

MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:myView];

效果

可以看到坐标系是正常的UIKit坐标系。

然后 我们在上面绘制一个文字"田" 在上述drawRect的最后添加

//绘制一些文字
NSString *str = @"田";
[str drawAtPoint:CGPointMake(CGRectGetWidth(rect) / , CGRectGetHeight(rect)/) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:],NSForegroundColorAttributeName:[UIColor greenColor]}];

最后 我们在右下角绘制一个红心,但是 我们希望红心是反过来的。这里用到了上面所说的绘制状态堆栈 继续在drawRect的最后添加如下代码

//保存上面的绘制状态
CGContextSaveGState(context);
//这次的操作不会影响上面的操作 因为已经保存了
//设置坐标系的原点在当前举行的右下方
CGContextTranslateCTM(context, rect.size.width, rect.size.height);
//将坐标系旋转180度
CGContextRotateCTM(context, M_PI);
NSString *redHeart = @"♥️";
//在这个坐标系下绘制的文字是相反的
[redHeart drawAtPoint:CGPointMake(, ) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:]}];
CGContextRestoreGState(context);

效果:

这里初学者可能不懂到底是怎么回事了(装逼 其实我也是初学者)。好了,让我们跟随着大神的脚步一步一步弄明白吧!

CGContextTranslateCTM(context, rect.size.width, rect.size.height);

这行代码把坐标系移动到右下角

如图:

接着把坐标系旋转180度

CGContextRotateCTM(context, M_PI);

这个时候的坐标系

这个时候 参考这个坐标系 进行绘制。看到的都是反过来的。

最新文章

  1. Web性能优化:基本思路和常用工具
  2. Java服务器对外提供接口以及Android端向服务器请求数据
  3. Leetcode House Robber II
  4. Celery,Tornado,Supervisor构建和谐的分布式系统
  5. 你所不了解的setTimeout
  6. ext 3.x 让uploadPanel支持swfupload
  7. 【转】【C#】C#性能优化总结
  8. Android操作系统11种传感器介绍
  9. 发送一个简单的http get 请求并且响应
  10. Altium Designer6打印PCB 设置
  11. 在开启bin-log日志下Mysql报错
  12. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题四 最短路练习 POJ 2387 Til the Cows Come Home
  13. iOS开发-正则表达式3种形式
  14. java web 之 listen 与 filter
  15. Java异常处理认识
  16. python基础--absl.flags
  17. Python_序列化和反序列化模块
  18. java异常处理解决方案
  19. 【翻译】go memory model
  20. C# MVC+EF—页面搭建

热门文章

  1. 使用AOP+Annotation实现操作日志记录
  2. easyui datagrid 动态操作editor 的方法
  3. 51nod 算法马拉松18 A 染色问题
  4. java.lang.IllegalArgumentException: Illegal character in query at index 261
  5. PHP中new static()与new self()的比较
  6. 使用javascript改变图片路径
  7. hibernate(1) —— 入门
  8. jQuery插件中文乱码解决办法
  9. 基础理解2:CSS3按钮动画
  10. Mac ping localhost 地址变化