概念部分
Core Graphics:
利用Quartz技术,以高保真的输出进行轻量级二维渲染。基于路径的绘制处理,抗锯齿渲染、渐变、图像、色彩管理、PDF文档,以及更多。
Core Graphics 是基于Quartz高级绘图引擎。它提供了低水平的轻量级2D渲染,具有无与伦比的输出保真度。你用这个框架来处理基于路径的绘制、变换、色彩管理、屏幕绘制,图案,渐变和阴影的图像数据管理、图像创作、图像掩模,以及PDF文档的创建、显示、和解析。
在MacOS,核心图形还包括与显示硬件工作服务,低级别的用户输入事件和视窗系统。
传送阵:https://developer.apple.com/documentation/coregraphics
根据苹果的描述,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 绘图引擎来绘制的,绘制流程如下:
- 获取上下文 Context(画布)
- 创建路径(自定义或者调用系统的API)并添加到上下文中。
- 进行绘图内容的设置(画笔颜色、粗细、填充区域颜色、阴影、连接点形状等)
- 开始绘图(CGContextDrawPath)
- 释放路径(CGPathRelease)
Graphics Context
A Quartz 2D drawing destination.
- Graphics Context是一个数据类型(CGContextRef),封装了Quartz绘制图像到输出设备的信息。输出设备可以是PDF文件、Bitmap或者显示器的窗口上。Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、字体信息、混合模式等
- Quartz中所有的对象都是绘制到一个Graphics Context中
- 当用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,或者绘制图表等需求。虽然不属于常用功能,但是开发过程中难免会遇到一些问题或需求,到时候也多了一种解决问题的途径,至于怎么解决方便,需要视情况而定。
网友评论