【OC】Core Graphics

概念部分

Core Graphics:

利用Quartz技术,以高保真的输出进行轻量级二维渲染。基于路径的绘制处理,抗锯齿渲染、渐变、图像、色彩管理、PDF文档,以及更多。
Core Graphics 是基于Quartz高级绘图引擎。它提供了低水平的轻量级2D渲染,具有无与伦比的输出保真度。你用这个框架来处理基于路径的绘制、变换、色彩管理、屏幕绘制,图案,渐变和阴影的图像数据管理、图像创作、图像掩模,以及PDF文档的创建、显示、和解析。
在MacOS,核心图形还包括与显示硬件工作服务,低级别的用户输入事件和视窗系统。
传送阵:https://developer.apple.com/documentation/coregraphics

层级关系.png

根据苹果的描述,UIKit是我们最容易也是最常接触到的框架。绝大多数图形界面都由UIKit完成。但是UIKit依赖于Core Graphics框架,也是基于Core Graphics框架实现的。如果想要完成某些更底层的功能或者追求极致的性能,那么依然推荐使用Core Graphics完成。

Core Graphics和UIKit在实际使用中也存在以下这些差异:

Core Graphics其实是一套基于C的API框架,使用了Quartz作为绘图引擎。这也就意味着它不是面向对象的。
Core Graphics需要一个图形上下文(Context)。所谓的图形上下文(Context),说白了就是一张画布。这一点非常容易理解,Core Graphics提供了一系列绘图API,自然需要指定在哪里画图。因此很多API都需要一个上下文(Context)参数。
Core Graphics的图形上下文(Context)是堆栈式的。只能在栈顶的上下文(画布)上画图。
Core Graphics中有一些API,名称不同却有着相似的功能,新手只需要掌握一种,并能够看懂其他的即可。

Quartz:

允许用户浏览、编辑和保存图像,使用幻灯片和Core Image的过滤器。
这个文档集合为Quartz framework提供了API参考,特别是对于Quartz Composer、Image Kit和PDFKit。Quartz Composer API支持处理和渲染图形数据,并允许开发人员为Quartz Composer 开发工具创建自定义补丁程序。Image Kit提供浏览、用户界面支持编辑和保存图像,显示幻灯片浏览,预览图像滤波器的核心。PDF Kit 是一种允许应用程序显示和操作PDF文档的技术。

Quartz 2D:

Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任何装置上,使用可以得到的最佳分辨率,产生相同的输出
Quartz 2D API可以实现许多功能,如基于路径的绘图、透明度、阴影、颜色管理、反锯齿、PDF文档生成和PDF元数据访问等
Quartz 2D API是Core Graphic框架的一部分,因此其中的很多数据类型和方法都是以CG开头的。会经常见到Quartz 2D(Quartz)和Core Graphics两个术语交互使用
Quartz 2D与分辨率和设备无关,因此在使用Quartz 2D绘图时,无需考虑最终绘图的目标设备

图形和图像:

图形:以路径的方式描述的一个形状,在应用程序运行时,实时绘制(渲染/Rending)的形状
图像:是以二进制数据的形式描述的一块像素点阵,在应用程序运行时,直接将该像素点阵逐一绘制在屏幕上
#所以不难看出图形的性能一般都会比图像高

正题

综上所述,我们了解到Core Graphics 主要通过 Quartz 2D 绘图引擎来绘制的,绘制流程如下:

  1. 获取上下文 Context(画布)
  2. 创建路径(自定义或者调用系统的API)并添加到上下文中。
  3. 进行绘图内容的设置(画笔颜色、粗细、填充区域颜色、阴影、连接点形状等)
  4. 开始绘图(CGContextDrawPath)
  5. 释放路径(CGPathRelease)
Graphics Context

A Quartz 2D drawing destination.

  1. Graphics Context是一个数据类型(CGContextRef),封装了Quartz绘制图像到输出设备的信息。输出设备可以是PDF文件、Bitmap或者显示器的窗口上。Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、字体信息、混合模式等
  2. Quartz中所有的对象都是绘制到一个Graphics Context中
  3. 当用Quartz绘图时,所有设备相关的特性都包含在Graphics Context中。换句话说,我们可以简单地给Quartz绘图序列指定不同的Graphics Context,就可将相同的图像绘制到不同的设备上。而不需要任何设备相关的计算,这些都由Quartz替我们完成

指定不同的上下文便可以在不同的设备上绘图,上下文种类:

1.Bitmap Graphics Context
2.PDF Graphics Context
3.Window Graphics Context
4.Layer Graphics Context
5.Printer Graphics Context

Core Graphics 基本使用

// 重写drawRect:方法
// 并不是说一提到绘图,就一定得重写drawRect方法,只是因为通常情况下我们一般采用在drawRect方法里获取context这种方式。
// drawRect方法什么时候触发
// 1.当view第一次显示到屏幕上时;
// 2.当调用view的setNeedsDisplay或者setNeedsDisplayInRect:方法时。

- (void)drawRect:(CGRect)rect{

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // 绘制线段
    CGContextMoveToPoint(ctx, 20, 80); // 起点
    CGContextAddLineToPoint(ctx, self.frame.size.width-10, 80); //终点
    [[UIColor redColor] set]; // 两种设置颜色的方式都可以
    CGContextSetLineWidth(ctx, 2.0f); // 线的宽度
    CGContextSetLineCap(ctx, kCGLineCapRound); // 起点和重点圆角
    CGContextSetLineJoin(ctx, kCGLineJoinRound); // 转角圆角
    CGContextStrokePath(ctx); // 渲染(直线只能绘制空心的,不能调用CGContextFillPath(ctx);)
    
    // 绘制三角形
    CGContextMoveToPoint(ctx, 10, 150);
    CGContextAddLineToPoint(ctx, 60, 100);
    CGContextAddLineToPoint(ctx, 100, 150);
    [[UIColor purpleColor] set];
    CGContextClosePath(ctx);
    CGContextStrokePath(ctx);
    
    // 绘制矩形
    CGContextAddRect(ctx, CGRectMake(20, 170, 100, 50));
    [[UIColor orangeColor] set];
    CGContextFillPath(ctx);
    
    // 绘制圆弧
    CGContextAddArc(ctx, 200, 170, 50, M_PI, M_PI_4, 0);
    CGContextClosePath(ctx);
    CGContextFillPath(ctx);
    
    // 绘制椭圆 当宽高相等时 则为圆
    CGContextAddEllipseInRect(ctx, CGRectMake(10, 10, 50, 50));
    [[UIColor greenColor] set];
    CGContextFillPath(ctx);
    
    // 绘制文字
    NSString *str = @"hello world";
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSForegroundColorAttributeName] = [UIColor blackColor]; // 文字颜色
    dict[NSFontAttributeName] = [UIFont systemFontOfSize:14]; // 字体
    
    [str drawInRect:CGRectMake(20, 250, 300, 30) withAttributes:dict];
    
    // 绘制图片
    UIImage *img = [UIImage imageNamed:@"0B4846F9F76FEA53591D637427CBCC98.gif"];
    [img drawInRect:CGRectMake(20, 280, 80, 80)]; // 拉伸
    
    // 绘制可控曲线
    CGContextMoveToPoint(ctx, 50, 130);
    
    // 一个控制点
    CGContextAddQuadCurveToPoint(ctx, 0, 100, 25, 170);
    
    // 两个控制点
    CGContextAddCurveToPoint(ctx, 160, 250, 230, 250, 160, 290);
    CGContextSetLineWidth(ctx, 10);
    CGContextSetStrokeColorWithColor(ctx, [UIColor brownColor].CGColor);
    CGContextStrokePath(ctx);
    
    // 阴影 只影响此行代码之后绘制的图形
    CGContextSetShadowWithColor(ctx, CGSizeMake(5, 10), 0.5, [UIColor redColor].CGColor);
    
    // 绘制渐变
    
    // 1. 辐射渐变
    // start point 光源
    // end point 投影区域以此为中心,向四周辐射
    // 开始点和结束点构成了一个带有方向的直线向量
    // gradientLocations 渐变颜色的区间分布,locations的数组长度和colors一致。这个属性可不设,默认是nil,系统会平均分布颜色如果有特定需要可设置,数组设置为0 ~ 1之间单调递增。
    // radius 辐射半径
    
    CGFloat gradientLocations[] = {0.8, 0.3,0.1,1};
    CGContextDrawRadialGradient(ctx, CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), (__bridge CFArrayRef)[NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor,(id)[UIColor blackColor].CGColor,(id)[UIColor redColor].CGColor,(id)[UIColor blueColor].CGColor, nil], gradientLocations), CGPointMake(150, 150), 0, CGPointMake(150, 150), MAX(50, 50), 0);
    
    // 2. 线性渐变
    // KCGGradientDrawsAfterEndLocation 扩展整个渐变到渐变的终点之后的所有点
    // KCGGradientDrawsBeforeStartLocation扩展整个渐变到渐变的起点之前的所有点。
    // 0不扩展该渐变。
    CGContextDrawLinearGradient(ctx, CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), (__bridge CFArrayRef)[NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor,(id)[UIColor blackColor].CGColor,(id)[UIColor redColor].CGColor,(id)[UIColor blueColor].CGColor, nil], gradientLocations), CGPointMake(10, 10), CGPointMake(10, 50), 0);
}

Core Graphics 主要适用于封装一些样式比较独特的view,或者绘制图表等需求。虽然不属于常用功能,但是开发过程中难免会遇到一些问题或需求,到时候也多了一种解决问题的途径,至于怎么解决方便,需要视情况而定。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容