版本记录
| 版本号 | 时间 |
|---|---|
| V1.0 | 2017.08.08 |
前言
quartz是一个通用的术语,用于描述在iOS和MAC OS X中整个媒体层用到的多种技术 包括图形、动画、音频、适配。Quart 2D是一组二维绘图和渲染API,Core Graphic会使用到这组API,Quartz Core专指Core Animation用到的动画相关的库、API和类。CoreGraphics是UIKit下的主要绘图系统,频繁的用于绘制自定义视图。Core Graphics是高度集成于UIView和其他UIKit部分的。Core Graphics数据结构和函数可以通过前缀CG来识别。在app中很多时候绘图等操作我们要利用CoreGraphic框架,它能绘制字符串、图形、渐变色等等,是一个很强大的工具。下面几篇就主要介绍CoreGraphics这个工具。
框架概览
我们先看一下框架CoreGraphics的组成。
#import <CoreGraphics/CoreGraphics.h>
这个框架包含以下的文件。
#ifndef COREGRAPHICS_H_
#define COREGRAPHICS_H_
#include <CoreGraphics/CGBase.h>
#include <CoreGraphics/CGAffineTransform.h>
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreGraphics/CGColor.h>
#include <CoreGraphics/CGColorConversionInfo.h>
#include <CoreGraphics/CGColorSpace.h>
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGDataConsumer.h>
#include <CoreGraphics/CGDataProvider.h>
#include <CoreGraphics/CGError.h>
#include <CoreGraphics/CGFont.h>
#include <CoreGraphics/CGFunction.h>
#include <CoreGraphics/CGGeometry.h>
#include <CoreGraphics/CGGradient.h>
#include <CoreGraphics/CGImage.h>
#include <CoreGraphics/CGLayer.h>
#include <CoreGraphics/CGPDFArray.h>
#include <CoreGraphics/CGPDFContentStream.h>
#include <CoreGraphics/CGPDFContext.h>
#include <CoreGraphics/CGPDFDictionary.h>
#include <CoreGraphics/CGPDFDocument.h>
#include <CoreGraphics/CGPDFObject.h>
#include <CoreGraphics/CGPDFOperatorTable.h>
#include <CoreGraphics/CGPDFPage.h>
#include <CoreGraphics/CGPDFScanner.h>
#include <CoreGraphics/CGPDFStream.h>
#include <CoreGraphics/CGPDFString.h>
#include <CoreGraphics/CGPath.h>
#include <CoreGraphics/CGPattern.h>
#include <CoreGraphics/CGShading.h>
#endif /* COREGRAPHICS_H_ */
使用这些文件时必须显式的引用。
#import <CoreGraphics/CoreGraphics.h>
框架的应用
1. 几个应用方向
这个框架主要应用的方向其实就是绘制自定义视图,几个具有代表性的方向:
- 绘制文字
- 根据任意路径绘制图像
- 绘制渐变色
- 抗锯齿渲染
2. 几个专业术语
还需要注意下面几个专业术语:
- 路径
path - 阴影
shadow - 笔画
stroke - 剪裁路径
Clip Path - 线条粗细
Line Width - 混合模式
Blend Mode - 填充色 Fill
Color - 当前形变矩阵
Current Transform Matrix - 线条图案
Line Dash
3. 几个重要概念
上下文 Context
这个是绘图中最重要的概念,相当于我们画图的画布,我们可以简单地给Quartz绘图序列指定不同的Graphics Context,就可将相同的图像绘制到不同的设备上。而不需要任何设备相关的计算,这些都由Quartz替我们完成。
我们还可以从下面角度理解上下文。
- 一个
Graphics Context表示一个绘制目标。它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息。 -
Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、字体信息、混合模式等。 - 在
iOS应用程序中,如果要在屏幕上进行绘制,需要创建一个UIView对象,并实现它的drawRect:方法。视图的drawRect:方法在视图显示在屏幕上及它的内容需要更新时被调用,通过调用UIGraphicsGetCurrentContext()方法可以获取当前的Graphics Context。 -
Quartz2D的坐标系统原点是左下角,UI控件的坐标系统原点是左上角,如果绘图的上下文,是使用UIGraphicsGetCurrentContext或者其他以UI开头的方法获取到的,在绘图时无需进行坐标转换。
主要有下面几种上下文:
Bitmap Graphics ContextPDF Graphics ContextWindow Graphics ContextLayer Graphics ContextPrinter Graphics Context
4. 框架架构及原理
下面看一下ios图像处理模块的经典原理配图。

最上层是UIKit框架,这是服务于Application的最前端框架,封装了所有控件类和操作;在其之下是Core Animation框架,借助与这个框架,Apple向开发人员提供了非常方便的动画处理功能和图像渲染功能。再往下,分离成基于GPU绘图的OpenGL ES层和基于CPU绘图的Core Graphic层。最底层的就是支持最终绘图的硬件平台,包括GPU,CPU,缓存,总线等等。
下面看一下CoreAnimation渲染。

这里虽然画着是他们都具有很明显的分隔,但是实际上他们的应用是十分紧密的,可以看一下下面的原理图。

这里可以看见,CPU和GPU都可以绘图,不过最终都是送到GPU进行显示了。

下面看几个容易混淆的概念CoreGraphics、QuartzCore和Quartz。
-
CoreGraphics.framework
- Quartz 2D : API manages the graphic context and implements drawing.
- Quartz Services : API provides low level access to the window server. This includes display hardware, resolution, refresh rate, and others.
-
QuartzCore.framework
- Core Animation : Objective-C API to do 2D animation.
- Core Image: image and video processing (filters, warp, transitions).iOS 5
-
Quartz.framework (OS X only)
- Image Kit: display and edit images.
- PDF Kit: display and edit PDFs.
- Quartz Composer: display Quartz Composer compositions.
- QuickLookUI: preview media elements.
-
其它一些Quartz技术:
- Quartz Extreme: GPU acceleration for Quartz Composer.
- QuartzGL (aka "Quartz 2D Extreme"): GPU acceleration for Quartz 2D.
5. 几个重要的问题
Quartz2D坐标转换
-
CGContextRotateCTM(CGContextRef c, CGFloat angle)方法可以相对原点旋转上下文坐标系。
-CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)方法可以相对原点平移上下文坐标系。 -
CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)方法可以缩放上下文坐标系。
注意:
- 转换坐标系前,使用
CGContextSaveGState(CGContextRef c)保存当前上下文状态。 - 坐标系转换后,使用
CGContextRestoreGState(CGContextRef c)可以恢复之前保存的上下文状态。
drawRect:方法注意事项
- 是在
UIViewController的loadView和viewDidLoad两方法之后调用的。 - 如果在
UIView初始化时没有设置CGRect,drawRect:将不会被自动调用。 - 如果设置UIView的
contentMode属性值为UIViewContentModeRedraw,那么将在每次更改frame时自动调用drawRect:。 - 如果使用UIView绘图,只能在
drawRect:方法中获取相应的CGContextRef并绘图。而在其他方法中获取的CGContextRef不能用于绘图。 - 重绘时应该调用
setNeedsDisplay,而不能直接调用drawRect:,setNeedsDisplay会自动调用drawRect:。
内存管理问题
- Quartz2D是C语言的框架,并且部分需要自己管理内存,使用含
Create或Copy的函数创建的对象,使用完后必须释放,否则将导致内存泄露。 - 使用不含有
Create或Copy的函数获取的对象,则不需要释放。 - 如果
retain了一个对象,不再使用时,需要将其release掉。可以使用Quartz 2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。也可以使用Core Foundation的CFRetain和CFRelease。注意不能传递NULL值给这些函数。
参考文章
1. iOS 2D Graphic(1)—— Concept 基本概念和原理
2. 整理一下CoreGraphic和Quartz2D的知识(一)
后记
未完,待续~~~
