【重读iOS】CoreGraphics&Quartz 2D

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【重读iOS】CoreGraphics&Quartz 2D相关的知识,希望对你有一定的参考价值。

参考技术A

从这段话理解, Quartz 2D 只是一套API, CoreGraphic 建立了一套 图形绘制 的体系。 CoreGraphic 中那些提供图形绘制功能的API,开放出来集合成了 Quartz 2D 。

核心为The Graphics Context,即CGContextRef。

graphics context并不是绘制的输出目标,但是它包含了绘制和输出所需的所有数据,是一个封装。针对不同的输出,有不同的context封装,所以一定程度,可以把context理解为输出目标。或者说对于输出目标,开发者也只能接触到context这个级别了。

总之context包含了绘制所有的参数,这也正是context这类角色的作用,只需要向context里输入绘制要求就可以了,剩余的它来处理。

就这6种输出目标:

PDF跟打印机没什么可说的,bitmap就是生成一个位图,window就是窗口,iOS里就是view,这里的Layer不是跟view一起的CALayer,而是CGLayer。CGLayer作用就是单图形的复用,替代原本用图片做的事,要更高效些。

所以内容就清晰的分为了两大部分: 1. 针对绘制目标的特殊处理,bigmap CGLayer 2. 绘制指令,path color shadow等

路径是什么?理解这个首先要理解 Quartz 2D 的绘制模式:

所以图形根本是线条,这个线条就是路径。

绘制路径的手段有:

CGContextMoveToPoint CGContextAddLineToPoint 搞定所有只有直线的图形

CGContextAddArcToPoint
这个就是指定圆心、半径、开始角度、结束角度,很好理解

CGContextAddArc
这个画圆弧的逻辑是:当前点+这个方法里的两个点,3个点构成一个夹角,然后画一个圆弧和这两条线都相切。这个方法在画圆角矩形的时候很好用,因为圆弧结束后还会把直线部分也一起画出来。

双控制点: CGContextAddCurveToPoint

单控制点: CGContextAddQuadCurveToPoint

然后是方便的添加矩形、椭圆。变化性最大的就是贝塞尔曲线了,可以模拟很多情况。

路线绘制好后还可以设置样式:

graphics context的混合模式,并不是指view和其他view,或layer之间的混合,而是一次绘制过程中,对某个点的多次上色之前的混合。就像绘画时,在鼻子上画了黄色,然后加点白色表现高光。

之后的绘制只会在被切出来的那个区域,其他区域绘制无效。

trasnform是对绘制的坐标进行了转换,前面都是说如何绘制出一个图,有了完整的图形后,可以用trasnform来对它进行整体的转换:移动、旋转、缩放以及这3个的叠加效果。

位图是什么?

一个位图就是一个像素数组,每个像素表示图片里的一个点。显示器上的图像都是一个个像素构成的,每个像素有自己的颜色,如果建一个表,把显示器上的每个像素的颜色都记录到表里,这个表数组就是一个位图bitmap。常用的JPEG PNG都是位图,当然这些图片都是压缩过得,内存和像素颜色不是一一对应的,但现实到屏幕之前一定会做解压。

有位图,就有对应的矢量图,它是由一系列计算机指令来描述和记录一幅图,显示之前再从这些指令从新把图绘制出来。

用一个圆来做例子,位图就是一张图,记录了每个位置的像素,跟其他的图没有不同。而矢量图可能就是一个命令: circle(radius:5,center:(20,20),color:...)

矢量图可能就要依赖于系统对指令的解析,而且绘制也需要消耗性能,但存储和传输更方便,而且一个很大的好处是可以应对不同的分辨率。

回到 Quartz 2D ,bitmap的context的作用就是把绘制的截图输出到一张图片里,常见的应用就是屏幕截图了。

核心方法:

mask在对个地方可以见到:这里的mask,CALayer里的mask,就是圆角的那个,哈希表里也有mask。总的来说就就是使用一种规则屏蔽掉某些数据,图像之间处理的mask,像这里,一般是根据alpha数据来的。alpha>0的地方图像显示,alpha==0的地方图像屏蔽。

CAlayer是负责view的内容显示的,而CGLayer和它完全不同,它并不做显示,而是存储。构造一个样式,比如自己绘制一个小星星,然后要重用这个小星星,两个方案:1. 使用bitmap,即把绘制的小星星变成一张图,想怎么用都可以。 2.使用CGLayer保存绘制结果。

可以理解CGLayer为对一个图形的引用、保存,可以在需要的地方绘制出来,可以看成是一种特殊的图片,消耗更小、更高效复用的图片。

除了重复绘制,高性能离屏渲染(High-quality offscreen),缓冲数据(Buffering)时也可以使用。Buffering的场景不是很清楚,但High-quality offscreen可以用于复杂图形的副线程绘制,在副线程把复杂图形绘制出来,然后存储在CGLayer里,在显示的时候直接显示,略去绘制过程的性能影响。

核心方法:

CoreGraphics 库在 iOS4 而不是 iOS3 中泄漏?

【中文标题】CoreGraphics 库在 iOS4 而不是 iOS3 中泄漏?【英文标题】:CoreGraphics Library Leaking in iOS4 and not iOS3? 【发布时间】:2010-11-04 16:20:55 【问题描述】:

我正在使用工具检查我的应用程序中的内存泄漏。iOS 3.1.x 没有显示任何泄漏。 但是,当我在 iOS4 iPhone 上进行相同的测试时,我从 CoreGraphics 库中得到了泄漏。

有没有人遇到过类似的问题?是操作系统本身的问题吗?

非常感谢

【问题讨论】:

【参考方案1】:

细节如此之少,很难说清楚。然而,在比较 3.0 到 3.1 和 3.1 到 4.x 时,我遇到了与 SDK 版本相关的泄漏和其他与 iOS 代码相关的错误功能。我认为与我的预期相比,iOS SDK 相对错误(非常完善的 Apple API)。

【讨论】:

以上是关于【重读iOS】CoreGraphics&Quartz 2D的主要内容,如果未能解决你的问题,请参考以下文章

iOS 动画篇 CADisplayLink与CoreGraphics实现动画

iOS开发CoreGraphics核心图形框架之一——CGPath的应用

iOS:CoreGraphics - 使用 CGContextClip 和 lineCap = .Round 剪裁弧线

CoreGraphics 库在 iOS4 而不是 iOS3 中泄漏?

有关iOS使用CoreGraphics部分机型出现背景红块问题

如何在两个单独的图层上绘制iOS,coregraphics