Quartz 2D概览
页面(Page):Quartz 2D使用画笔模型——每一个绘图操作在一块输出画布上进行一层绘制(paint),这个画布就叫做页面。
绘制目标:图形内容(Graphics Context)是一个复杂的数据类型(CGContextRef),用于封装Quartz用于绘图的信息,用来在输出设备上draw images。
Quartz 2D模糊数据类型:从模糊数据类型创建对象,在应用程序中用其完成特殊的绘制并输出。
图形状态(Graphics states):Quartz 2D根据当前的图形状态来修改绘图结果。
Quartz 2D坐标系统:Quratz 使用current transformation matrix(CTM)完成了具体的坐标系统的无关性(完成了user space和device space的映射)。
内存管理:对象的所有权, Quratz 使用Core Foundation的内存管理模型,引用计数。
Graphics Contexts
Graphics Contexts代表一个绘图目的地。其包含绘图参数和所有与设备相关的信息,这些在绘制系统执行绘制命令的时候是需要的。
可以使用Quartz context创建函数或者IOS的UIKit框架去得到一个Graphics Context。
Graphics Context在代码的中的数据类型为CGContextRef,是一个不透明的data type。
当得到一个Graphics Context之后,可以使用Quratz 2D函数去绘制context,在context上进行一些操作(如translations),改变graphics 的状态参数,如line的宽度和fill color。
IOS中在一个view Graphics Context上绘制
先建立一个UIView对象,然后实现其drawRect:方法去进行绘制。
当view变的可见的时候或者其内容需要更新的时候,view的drawRect:方法会被调用。
在调用自定义的drawRect:方法之前,view对象会自动的配置其绘制环境,然后代码可以立即的绘制。
作为配置的一部分,UIView对象先为当前的绘制环境创建一个Graphics Context。
UIKit使用的缺省坐标系统与Quartz的坐标系统不相同。
创建一个bitmap Graphics Context
bitmap Graphics Context接受一个指针,指向内存缓冲区,其包含一个bitmap的存储空间。
当我们在bitmap Graphics Context上paint时,此缓冲区会被更新。
当我们释放了Graphics Context,我们将有一个在指定像素格式下的完全更新bitmap。
paths
一个path有一个或者多个shapes,或者subpaths定义。
path的创建和path的painting
首先创建一个path
当我们在graphics context下创建一个path,可应该先调用Quartz的函数CGContextBeginPath,
接着设置第一个shape或者subpath的开始点,在path中调用函数CGContextMoveToPoint。
当初始点设置好以后,就可以添加lines,arcs,curves,但要注意一下几点:
在开始新的path之前,要调用函数CGContextBeginPath。
lines,arcs,curves都是从current point开始绘制,一个空的path没有current point,我们必须调用CGContextMoveToPoint去设置或者调用一个函数隐含的设置了当前值。
调用函数CGContextClosePath去关闭current subpath。接下来会开始一个新的subpath,即时我们不去那个设置开始点。
当我们绘制一个arcs时,Quratz会在current point 和start point之间绘制一条直线。
创建一个path不等于绘制path,所以我们必须调用paint 函数去fill 或者stroke path。
当我们paint一个path之后,graphics context会被刷新,但是我们有些时候不想就失去此path,特别是在一些复杂的场景下我们想多次用到。 Quartz提供了两个数据类型用于创建可重复用的path(CGPathRef和CGMutablePathRef)。
我们可以调用函数CGPathCreateMutable去创建一个可变的CGPath对象,然后去添加lines,arcs,curves等。
当想要去显示时,要请求Quartz去paint
我们可以选择path的stroke(勾画),path的fill(填充)。我们也可以使用path去限制其他对象drawing的范围,此称为clipping area。
the building blocks(建筑块???)
subpaths(路径过程)是由lines,arcs(弧形),curves(曲线)组建成的,Quartz也提供了一些方便的函数用于添加矩形和椭圆。
points(点):我们可以调用函数CGContextMoveToPoint去指定一个新的subpath的开始位置。Quratz会保存当前点(current point)的记录。
Lines:一个line定义了他的endpoint,line的开始点为current(当前) point。我们用函数CGContextAddLineToPoint去在subpath上添加一条线。
Arcs:Arcs是圆的一部分。Quratz提供了两个函数用来创建arcs。
函数CGContextAddArc用来从一个圆中创建一个曲线段。
函数CGContextAddArcToPoint是一个理想的方法用来圆一个矩形的角。Quratz使用我们提供的endpoint去创建两个切线。
curves:Quadratic 和Bezier 曲线可以指定很多形状的曲线。
使用函数CGContextAddQuadCurveToPoint去使用添加一个二次Bezier曲线,要我们指定一个control point和endpoint。
使用函数CGContextAddCurveToPoint去使用一个三次Bezier 曲线,要我们指定control point和endpoint。
ellipses:可以在current path 下通过调用函数CGContextAddEllipseInRect:添加一个椭圆。
Rectangles:通过调用函数CGContextAddRect去在current path下添加一个矩形。
closing a subpath
应用程序应该调用CGContextClosePath去关闭current subpath。
当closing 一个subpath之后,如果应用程序又添加一个额外的line,arcs或者其他的,Quartz会开始一个新的subpath。
Paint path
影响stroking(画笔)的参数,这些参数是graphics state的一部分
CGContextSetLineWidth 设置线的宽度(粗细)
CGContextSetLineJoin
CGContextSetLineCap
CGContextSetMiterLimit
CGContextSetLineDash 画虚线
CGContextSetStrokeColor 设置线条颜色
CGContextSetStrokeColorSpace
CGContextSetStrokeColorWithColor
CGContextSetStrokePattern
CGContextSetRGBFillColor 填充颜色
给路径中增加图形
CGContextAddRect 在路径中增加以矩形
CGContextAddRects 在路径中增加多个矩形
CGContextAddArcToPoint 在矩形中增加一个弧线
CGContextAddArc 在路径中增加一个圆弧
stroking path的函数
CGContextStrokePath 用非填充的方式绘制当前路径
CGContextFillPath 以填充的方式绘制当前路径
CGContextStrokeRect 直接在路径中以非填充方式绘制矩形
CGContextFillRect 以填充的方式在直接在当前路径中绘制矩形
CGContextStrokeRectWithWidth 以指定的宽度绘制矩形
CGContextStrokeEllipseInRect 绘制椭圆
CGContextStrokeLineSegments 绘制一连串线条
CGContextDrawPath 后来添加入此序列的,调用此方法前要关闭路径 绘制当前路径,可以选填充绘制或不填充绘制
Transforms
Quartz 2D定义了两个完全独立的坐标空间:用户空间,其代表当前的页面,设备空间,其代表设备的原始分辨率。
Quartz中和转换相关的函数
修改当前转换矩阵:
在我们改变CTM之前,我们需要去保存graphics 状态,以便我们在绘制之后还原其状态。
在我们绘制一个image之前,我们可以操纵CTM去rotate,scale,translate。
Translation是移动坐标系统的初始点,通过调用函数CGContextTranslateCTM去改变
Rotation是改变坐标系统指定的角度。通过调用函数CGContextRotateCTM去指定具体的角度,弧度。
Scaling改变坐标空间的scale。能有效的压缩或者延伸image。我们通过调用函数CGContextScaleCTM去指定具体的x轴和y轴的scaling factors。
Concatenation累积转换,一次发起两次或者两次以上的transformations。
累积转换的顺序不同我们会得到不同的结果:
创建affine(仿射线) transforms
affine transform函数CGContextConcatCTM可以在矩阵上应用
affine transform函数有操作的,也有返回的,返回的类型为CGAffineTransform .
绘制Images
要注意的一点是 :因为用Quartz image 绘制images是倒置的,Quartz image在初始点为左下角的位置绘制,但是UIView将其初始点放置在左上角。
首先要获取一个图片
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"Demo.png" ofType:nil]; 获取文件在项目中的路径
UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; 根据文件名加载图片到img。扩展:让img不会倒置见备注。
其次:CGImageRef image = [img CGImage]; 获取一个atlas图像的CGImageRefimg上下文句柄。扩展:在CGImageRef中不会倒置的实现见备注 CGImageRef是一个指向Quartz 2D中的一个内部结构的指针,这个结构包含了这幅图像所有和显示相关的信息。
将图形绘制到上下文中
CGContextDrawTiledImage 平铺图形显示
CGContextClip 将路径中的矩形设置为裁剪区
CGContextClipToRect 是上面和在路径中添加矩形区的结合方法
CGContextGetClipBoundingBox 获取上下问中的剪切矩形
最后在dealloc中需要释放 CGImageRelease(image);