quartz 2d简介
quartz 2d是苹果公司开发的一个二维图形绘制引擎,同时支持ios和mac系统。
它是一套基于c的api框架,提供了低级别、轻量级、高保真度的2d渲染。它能完成的工作有:
- 绘制图形 : 线条\三角形\矩形\圆\弧等
- 绘制文字
- 绘制\生成图片(图像)
- 读取\生成pdf
- 截图\裁剪图片
- 自定义ui控件
- …
quartz 2d进行绘图
ios绘图技术主要有uikit,quartz 2d,core animation和opengl es。我们平常对uikit应该不陌生,而quartz 2d与uikit的一个区别是:
quartz 2d的坐标原点在左下角,而uikit的坐标原点在左上角。
在开始前作下准备工作:创建一个新的cocoa touch class,继承自uiview,然后去storyboard把view视图关联下新创建的类。
1.填充和描边
重写绘图方法drawrect(),添加代码:
override func drawrect(rect: cgrect) {
//填充背景
uicolor.browncolor().setfill()
//填充矩形
uirectfill(rect)
uicolor.whitecolor().setstroke()
//矩形描边
let frame = cgrectmake(10, 24, 100, 300)
uirectframe(frame)
}
运行效果:
2.绘制三角形
确定三个点就能绘制出三角形,当然其他的图形(如矩形)也是类似。
在drawrect()里添加代码:
override func drawrect(rect: cgrect) {
let context = uigraphicsgetcurrentcontext()
//绘制起始点
cgcontextmovetopoint(context, 120, 104)
//从起始点到这一点
cgcontextaddlinetopoint(context, 150, 204)
cgcontextaddlinetopoint(context, 200, 104)
//闭合路径
cgcontextclosepath(context)
uicolor.blackcolor().setstroke()
uicolor.greencolor().setfill()
//绘制路径
cgcontextdrawpath(context, cgpathdrawingmode.fillstroke)
}
运行效果:
依此类推,大家可以试试怎么去画长方形,正方形和不规则多边形。
3.绘制图片和文字
首先准备一张图片放入工程中,注意不要放在assets.xcassets文件夹下,因为这里寻找的路径是在工程文件夹。而如果把图片放在assets.xcassets文件夹下,就要使用另外的一种方法。
在drawrect()里添加代码:
override func drawrect(rect: cgrect) {
//绘制图片和文字
//这种方式添加图片需要把图片放到根目录下,而不是assets.xcassets下
let imagepath = nsbundle.mainbundle().pathforresource("头像004", oftype: "jpg")
let image = uiimage(contentsoffile: imagepath!)
//具体位置根据你的图片来调整
image?.drawinrect(cgrectmake(100,100, 200, 200))
let title = "头像"
let font = uifont.systemfontofsize(44)
let attr = [nsfontattributename:font]
title.drawatpoint(cgpointmake(100, 20), withattributes: attr)
}
运行效果:
quartz 2d中的坐标变换
注意:坐标变换操作必须要在添加图形之前,如果设置在添加图形之后的话会无效。
我们先画一个正方形做完参考:
override func drawrect(rect: cgrect) {
let context = uigraphicsgetcurrentcontext()
cgcontextsetlinewidth(context, 2.0)
cgcontextsetstrokecolorwithcolor(context, uicolor.redcolor().cgcolor)
let rectangle = cgrectmake(125, 50, 50, 50)
cgcontextaddrect(context, rectangle)
cgcontextstrokepath(context)
}
1、平移
func cgcontexttranslatectm(c: cgcontext?, _ tx: cgfloat, _ ty: cgfloat)
该方法相当于把原来位于 (0, 0) 位置的坐标原点平移到 (tx, ty) 点。在平移后的坐标系统上绘制图形时,所有坐标点的 x 坐标都相当于增加了 tx,所有点的 y 坐标都相当于增加了 ty。
override func drawrect(rect: cgrect) {
let context = uigraphicsgetcurrentcontext()
cgcontextsetlinewidth(context, 2.0)
cgcontextsetstrokecolorwithcolor(context, uicolor.redcolor().cgcolor)
cgcontexttranslatectm(context, -50, 25) // 向左向下平移
let rectangle = cgrectmake(125, 50, 50, 50)
cgcontextaddrect(context, rectangle)
cgcontextstrokepath(context)
}
2、缩放
func cgcontextscalectm(c: cgcontext?, _ sx: cgfloat, _ sy: cgfloat)
该方法控制坐标系统在水平方向和垂直方向上进行缩放。在缩放后的坐标系统上绘制图形时,所有点的 x 坐标都相当于乘以 sx 因子,所有点的 y 坐标都相当于乘以 sy 因子。
override func drawrect(rect: cgrect) {
let context = uigraphicsgetcurrentcontext()
cgcontextsetlinewidth(context, 2.0)
cgcontextsetstrokecolorwithcolor(context, uicolor.redcolor().cgcolor)
cgcontextscalectm(context, 0.5, 1)
let rectangle = cgrectmake(125, 50, 50, 50)
cgcontextaddrect(context, rectangle)
cgcontextstrokepath(context)
}
3、旋转
func cgcontextrotatectm(c: cgcontext?, _ angle: cgfloat)
该方法控制坐标系统旋转 angle 弧度。在缩放后的坐标系统上绘制图形时,所有坐标点的 x、y 坐标都相当于旋转了 angle弧度之后的坐标。
override func drawrect(rect: cgrect) {
let context = uigraphicsgetcurrentcontext()
cgcontextsetlinewidth(context, 2.0)
cgcontextsetstrokecolorwithcolor(context, uicolor.redcolor().cgcolor)
cgcontextrotatectm(context, cgfloat(m_pi_4))
let rectangle = cgrectmake(125, 50, 50, 50)
cgcontextaddrect(context, rectangle)
cgcontextstrokepath(context)
}
注意:旋转的时候,是整个 layer 都旋转了,所以 layer 看起来应该是这样的:
这个时候若想移动 view ,就应该按照这个旋转过的坐标系来移动:
override func drawrect(rect: cgrect) {
let context = uigraphicsgetcurrentcontext()
cgcontextsetlinewidth(context, 2.0)
cgcontextsetstrokecolorwithcolor(context, uicolor.redcolor().cgcolor)
cgcontextrotatectm(context, cgfloat(m_pi_4))
cgcontexttranslatectm(context, 0, -100) // 在新坐标系中向上移动100点,视图上看起来像是向右向上都移动了
let rectangle = cgrectmake(125, 50, 50, 50)
cgcontextaddrect(context, rectangle)
cgcontextstrokepath(context)
}