(是通过英文资料iOS Drawing扣扣巴巴一点点翻译过来的笔记。应该会有不少不对的地方,谅解~)
图形上下文(drawing context)是指在你的应用里有一个虚拟的画布(canvas)用来绘图。你可以通过“上下文”(虽然我也不清楚上下文是啥意思,就是context这个单词的翻译。。)来创建图像,文件和自定义视图,通过学习UIKit,Core Graphics和 Quartz里的基础绘图方法。
1.Framework框架
iOS的绘图程序主要源于UIKit和QuartzCore Framework。QuartzCore Framework就是我们常说的,Quartz或者Quartz 2D。Quartz这个名字比苹果内部贯彻的名字Core Graphics要出名的多,这本书(《iOS Drawing》)里提到的Quartz和Core Graphics都是同一个意思。大多以CG开头的c语言API都是取自Core Graphics,
✨通常我们说的框架有两种:一是,UIKit绘图框架;二是,Quartz;
✨✨🌟下面的章节会用特别多的例子来说明UIKit绘图和Quartz绘图的区别和联系,如何交互使用等等,请特别注意。
✨比如例子画一个圆角矩形框
✨通过UIKit
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:inset cornerRadius:12];
[bezierPath stroke];
✨通过Quartz
CGContextFillEllipseInRect(context,rect);
2.When to Draw是什么时候使用呢?
1.创建自定义视图;2.构建图像;3.创建pdf文件;4.处理核心图像
1.创建自定义视图 creating custom views
本质上,每一个UIKit的视图都是一个空的画布。你可以完全自定义的画出一个视图。你只需要在一个特殊的方法drawRect:方法里绘制出来,这个方法允许你自定义视图的样子通过UIKit和Quartz里的绘图方法。
2.构建图像 building images
在iOS中,你一可以引入一个UIKit image内容或重新使用一个UIImage单例。它允许你创建一个新的图像或者修改一个存在的图像。Drawing允许你处理自定义图像不依赖于已存在的库或图片文件。
3.创建pdf文件 creating PDFs
你可以绘制出一个UIKit pdf上下文,它既不直接出一个文件也不保存数据。它允许你处理来自app的pdf内容,分享,存储,或者展示它们。
4.处理核心图像 building with Core Graphics
你也许想一字节一字节地访问图片数据,这个需求用UIKit就不是很好完成,但是在Core Graphics的位图上下文中便可以完美地处理。比如通过Core Graphics把RGB图像转换为灰度图像。
3.上下文Contexts
每一个iOS绘图操作都从一个context开始。从概念上说,上下文和一个空白页或者一个空画布相似。它们包括了所有绘图中的状态和信息。
在iOS中,最重要的图形上下文有两个:位图(bitmap)上下文和PDF上下文。核心图形库还提供了第三个上下文的类型,它用来完成图片处理任务而非用来绘图。
1.位图上下文 Bitmap Context
位图上下文本质上是一个二维数组数据。这些数据的大小取决于每一个像素点的颜色类型代表着人什么。比如RGB图,灰度图等等。
2.PDF上下文 PDF Context
PDF很多地方和位图上下文相似,它们通过相同的命令和方法来绘制,你设置颜色或者绘制形状或文本就和绘制一个视图或者图像差不多。当然,他们也有不同的地方。
PDF以存有矢量数据。PDF上下文的内容也可能多于一页,你需要创建边界矩形来具体说明默认尺寸和每一页PDF页的位置。
3.核心图像上下文 Core Image Contexts
Core Image framework可以让你快速的处理图像。有了它,你可以处理滤镜,滤镜链,实现特点捕捉(可以找到照片中的脸和眼睛),分析图片使它自适应。
4.用UIKit创建一个上下文Establishing contexts in UIKit
1.创建一个位图上下文
✨注意所有方法等前缀,这里UI开头,都是用的是UIKit的方法。
a.基础位图上下文
b.上下文选择权许可允许以设备尺寸绘图(我也不知道我翻译的什么鬼。。。原文Context Opttions Enable Drawing at Device Scale)
鼓励使用第二种方法创建位图上下文。
2.创建PDF上下文
创建一个PDF上下文,你必须有一个文件路径或者可变data对象,还需要提供一个边界框,以及一个字典,用来具体说明元数据和安全信息。比如说,你想著名作者或者用户密码,文件权限等等。
5.用Quartz创建一个上下文。
✨这一个例子的方法均用的CG开头的方法,Core Graphics也就是Quartz的方法。
6.在上下文里绘图 Drawing into Contexts
确切的说,使用Quartz的方法在上下文里绘图。
1-5的内容是写在1-4里面的~
7.在UIKit上下文里面绘图 Drawing Within a UIKit Context
✨这个例子的关键在UIGraphicsGetCurrentContext()通过UIKit的方法得到CG的context。
UIKit简化了创建和管理上下文的方法,一句话就可以完成创建一个图像上下文或者PDF上下文,看看跟1-4,1-5比起来是不是简单多了?用UIGraphicsGetCurrentContext()方法就可以直接获取到当前的图像或者PDF上下文~
当然,在现在的UIKit里面还有更加先进的方法来完成绘制一个椭圆~~
同样是画了一个椭圆,却没有提到上下文context~是不是很神奇。(书里有一大段都是在描述没有上下文很神奇,我就不翻译了~)
发生了什么事情呢,事情是这样的。UIKit拥有一个图形上下文的堆栈,可以把绘图操作放到栈顶的上下文去完成。这些设置,比如说灰色,也都会推倒栈顶的上下文里去。
那么问题来了,怎么才能让核心绘图上下文和UIKit融为一体呢?有两个关键的方法就来了~
· 你可以手动推出一个上下文,通过UIGraphicsPushContext(context)方法。这个方法可以把上下文推到UIKit栈的顶端。
·你也可以调用UIGraphicsPopContext()。这个方法可以把堆栈顶端的上下文移除UIKit的上下文栈,激活堆栈的下一个上下文或者置空。
总结
总结来了~~
混合使用核心图像上下文(Core Graphics context)和UIKit绘图,有以下几步:
1.创建一个核心绘图上下文。
2.UIGraphicsPushContext(context)。
3.使用UIKit绘图方法和Quartz的绘图方法结合来完成绘图。
4.(取回上下文的内容,得到一个image)
5.释放上下文。
8.UIKit和Quartz的颜色
在iOS开发术语中有一个叫 toll free bridged(不用通行费就可以过桥。。。)的东西,什么意思呢,就是说很多核心库里面的数据类型也可也通过交换在UIKit里面使用。比如说,ARC里面的__bridge。但是不幸的是,这个桥梁在Quartz和UIKit的关系里却是缺席的,包括颜色。
在很多绘图的类里面,UIKit通过Objective-C把Quartz的方法和Core Graphics里面的类包装起来。比如UIColor里面包了个CGColor,UIBezierPath里面包了个CGPath,UIImage里面包了CGImage和CIImage。这些东西都不是等价的。虽然你可以很容易的访问到背后的Quartz元素,但着并不能算是一个桥。
9.画家模型 The Painter's Model
iOS用一个叫“画家模型”的东西在上下文中绘图。除非你特别说明,所有的画都会画在原有画的上面。就像一个画家物理绘图是一样的,
10.上下文状态 Context State
setFill 方法用颜色来涂满绘图边界线的内部。
setStroke 只是用来给绘图边界描一个边。
如图1-9.绿色是fill 。紫色是 stroke
通过CGContextSaveGState(context)和CGContextRestoreGState(context)可以实现保存之前的绘图状态。
代码和效果图如上。保存了之前第一次 绘图 的状态。
状态类型~
一个上下文可以存储很多种的状态,不仅仅是fill和stroke。下面我们用一个表来看看吧~
t
加粗字体提醒自己回头吧这个表翻译成中文
为什么越写到后面越来越卡,特别是倒入图片之后。。写着好累啊。。。还是把 drawing context这一章分开写算了。。。
后面还有几节,分别是
Context Coordinate System 上下文中的坐标系;
Clipping 剪辑;
Transforms 调整;
setting line parameters 线的参数设置;
总结;
然后第二章是 The Language of Geometry 几何语言
Points Versus Pixels 点和像素;
View Coordinates 视图坐标;
Key Structures 关键结构;
Using CGRectDivide() 使用前面这个方法;
Rectangle Utilities 矩形工具;
Fitting and Filling 拟合和填充;
Summary总结。