【OC】Core Graphics

作者: Richard_Wei | 来源:发表于2017-06-14 16:52 被阅读0次

    概念部分

    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,或者绘制图表等需求。虽然不属于常用功能,但是开发过程中难免会遇到一些问题或需求,到时候也多了一种解决问题的途径,至于怎么解决方便,需要视情况而定。

    相关文章

      网友评论

        本文标题:【OC】Core Graphics

        本文链接:https://www.haomeiwen.com/subject/ffoffxtx.html