前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >绘图-Core Graphics

绘图-Core Graphics

作者头像
進无尽
发布2018-09-12 18:36:36
1.5K0
发布2018-09-12 18:36:36
举报

前言

CGContext又叫图形上下文,相当于一块画布,以堆栈形式存放,只有在当前context上绘图才有效。iOS有分多种图形上下文,其中UIView自带提供的在drawRect:方法中通过UIGraphicsGetCurrentContext获取,还有专门为图片处理的context,UIGraphicsBeginImageContext函数生成,还有pdf的context等等。

Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。iOS支持两套图形API族:Core Graphics/QuartZ 2D 和OpenGL ES。前者提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变、遮蔽、图像数据管理、图像的创建、遮罩以及PDF文档的创建、显示和分析。

Quart 2D 是一组二位绘图和渲染API,Core Graphic会使用到这组API

这是一个绘图专用的API族,它经常被称为QuartZ或QuartZ 2D。Core Graphics是iOS上所有绘图功能的基石,包括UIKit。

顺便说一下,有代码工具 PaintCode 可以生成相应的 Core Graphics 代码,直接拖进工程中就可以使用,可以大幅加快开发进程,当然是你先学会使用PaintCode才行

简述

绘图的步骤:(在drawRect函数中) 1.获取绘图上下文 2.创建并设置路径 3.将路径添加到上下文 4.设置上下文状态 5.绘制路径 6.释放路径

在使用Core Graphics 时有许多方式获得一个图形上下文,这里我介绍两种最为常用的获取方法 第一种方法就是创建一个图片类型的上下文。 调用UIGraphicsBeginImageContextWithOptions函数就可获得用来处理图片的图形上下文。利用该上下文,你就可以在其上进行绘图,并生成图片。 调用UIGraphicsGetImageFromCurrentImageContext函数可从当前上下文中获取一个UIImage对象。记住在你所有的绘图操作后别忘了调用UIGraphicsEndImageContext函数关闭图形上下文。

第二种方法是利用cocoa为你生成的图形上下文。 当你子类化了一个UIView并实现了自己的drawRect:方法后,一旦drawRect:方法被调用,Cocoa就会为你创建一个图形上下文,此时你对图形上下文的所有绘图操作都会显示在UIView上。

Core Graphics 里面的类文件众多:

Paste_Image.png

让我们来看一下CGContext.h 里面的方法:

CGContextRef context = UIGraphicsGetCurrentContext(); 设置上下文                
CGContextMoveToPoint 开始画线
CGContextAddLineToPoint 画直线

CGContextAddEllipseInRect 画一椭圆
CGContextSetLineCap 设置线条终点形状        #三个枚举值
#1.kCGLineCapButt该属性值指定不绘制端点, 线条结尾处直接结束。这是默认值。
#2.kCGLineCapRound该属性值指定绘制圆形端点, 线条结尾处绘制一个直径为线条宽度的半圆
#3.kCGLineCapSquare该属性值指定绘制方形端点。线条结尾处绘制半个边长为线条宽度的正方形。需要说明的是,
#这种形状的端点与“butt”形状的端点十分相似,只是采用这种形式的端点的线条略长一点而已
CGContextSetLineDash 画虚线
CGContextAddRect 画一方框
CGContextStrokeRect 指定矩形
CGContextStrokeRectWithWidth 指定矩形线宽度
CGContextStrokeLineSegments 一些直线


CGContextAddArc 画已曲线 前俩店为中心 中间俩店为起始弧度 最后一数据为0则顺时针画 1则逆时针
CGContextAddArcToPoint(context,0,0, 2, 9, 40);//先画俩条线从point 到 弟1点 , 从弟1点到弟2点的线  切割里面的圆   
CGContextSetShadowWithColor 设置阴影   
CGContextSetRGBFillColor 这只填充颜色
CGContextSetRGBStrokeColor 画笔颜色设置    
CGContextSetFillColorSpace 颜色空间填充   
CGConextSetStrokeColorSpace 颜色空间画笔设置
CGContextFillRect 补充当前填充颜色的rect
CGContextSetAlaha 透明度


CGContextTranslateCTM 改变画布位置
CGContextSetLineWidth 设置线的宽度
CGContextAddRects 画多个线
CGContextAddQuadCurveToPoint 画曲线
CGContextStrokePath 开始绘制图片
CGContextDrawPath 设置绘制模式
CGContextClosePath 封闭当前线路
CGContextTranslateCTM(context, 0, rect.size.height);    
CGContextScaleCTM(context, 1.0, -1.0);反转画布      
CGContextSetInterpolationQuality 背景内置颜色质量等级 
CGImageCreateWithImageInRect 从原图片中取小图


字符串的 写入可用  nsstring本身的画图方法 
- (CGSize)drawInRect:  (CGRect)rect withFont:(UIFont *)font lineBreakMode:
(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment;来写进去即可

对图片放大缩小的功能就是慢了点  
UIGraphicsBeginImageContext(newSize);    
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();  
UIGraphicsEndImageContext();


CGColorGetComponents() 返回颜色的各个直 以及透明度 可用只读const float 来接收  是个数组


画图片 
CGImageRef image= CGImageRetain(img.CGImage);   
CGContextDrawImage(context, CGRectMake(10.0, height -100.0, 90.0, 90.0), image);


 实现逐变颜色填充方法
 CGContextClip(context);   
 CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();   
 CGFloat colors[] =    {  204.0 / 255.0, 224.0 / 255.0, 244.0 /  255.0, 1.00,       
     29.0 / 255.0, 156.0 / 255.0, 215.0 / 255.0, 1.00, 0.0 /     
     255.0,  50.0 / 255.0, 126.0 / 255.0, 1.00,    
  };  
 CGGradientRef gradient =CGGradientCreateWithColorComponents (rgb, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4));   
 CGColorSpaceRelease(rgb);             
 CGContextDrawLinearGradient(context,gradient,CGPointMake(0.0,0.0),CGPointMake(0.0,self.frame.size.height), kCGGradientDrawsBeforeStartLocation);

 **注意释放掉对象,已释放内存**
 注:  画完图后,必须    
 先用CGContextStrokePath来描线,即形状    
 后用CGContextFillPath来填充形状内的颜色.


 填充一个路径的时候,路径里面的子路径都是独立填充的。
 假如是重叠的路径,决定一个点是否被填充,有两种规则
 1,nonzero winding number rule:非零绕数规则,假如一个点被从左到右跨过,计数器+1,从右到左跨过,计数器-1,最后,如果结果是0,那么不填充,如果是非零,那么填充。
 2,even-odd rule: 奇偶规则,假如一个点被跨过,那么+1,最后是奇数,那么要被填充,偶数则不填充,和方向没有关系。


Function
Description  
CGContextEOFillPath 使用奇偶规则填充当前路径     
CGContextFillPath 使用非零绕数规则填充当前路径
CGContextFillRect 填充指定的矩形 
CGContextFillRects 填充指定的一些矩形 
CGContextFillEllipseInRect 填充指定矩形中的椭圆 
CGContextDrawPath 两个参数决定填充规则,kCGPathFill表示用非零绕数规则,kCGPathEOFill表示用奇偶规则,kCGPathFillStroke表示填充, kCGPathEOFillStroke表示描线,不是填充


设置当一个颜色覆盖上另外一个颜色,两个颜色怎么混合
默认方式是   
result = (alpha * foreground) + (1 - alpha) * background
CGContextSetBlendMode :设置blend mode.
CGContextSaveGState :保存blend mode.
CGContextRestoreGState:在没有保存之前,用这个函数还原blend mode.
CGContextSetBlendMode 混合俩种颜色

让我们来看一下CGPath.h 里面的方法:

Paste_Image.png

Creating and Managing Paths

CGPathCreateMutable  创建一个可变的图形路径。
CGPathCreateWithEllipseInRect   创建一个椭圆的不可变路径。
CGPathCreateWithRect    创建一个矩形的不可变路径。
CGPathCreateWithRoundedRect 创建一个圆角矩形的不可变路径。
CGPathCreateCopy    创建一个图形路径的不可变副本。
CGPathCreateCopyByTransformingPath  创建由变换矩阵变换的图形路径的不可变副本。
CGPathCreateCopyByDashingPath  创建另一个路径的虚线副本。
CGPathCreateCopyByStrokingPath   创建另一个路径的实线副本。
CGPathCreateMutableCopy    创建一个现有的图形路径可复制。
CGPathCreateMutableCopyByTransformingPath  创建一个图形路径的变换矩阵将可变副本。
CGPathRelease      减少图形路径
CGPathRetain        递增一个图形路径的保留计数。

Modifying Quartz Paths

CGPathAddArc   追加一个弧一个可变的图形路径,可能前面的直线段。
CGPathAddRelativeArc   追加一个弧一个可变的图形路径,可能前面的直线段。
CGPathAddArcToPoint  追加一个弧一个可变的图形路径,可能前面的直线段。
CGPathAddCurveToPoint  //绘制三次贝塞尔曲线
CGPathAddLines  追加新的线段图形路径数组的一个可变的。
CGPathAddLineToPoint   追加一条线段一个可变的图形路径。
CGPathAddPath   添加一个路径到一个可变的图形路径。
CGPathAddQuadCurveToPoint   //绘制二次贝塞尔曲线

CGPathAddRect   添加一个矩形,一个可变的图形路径。
CGPathAddRects  追加矩形可变图形路径数组。
CGPathAddRoundedRect   添加一个圆角矩形可变图形路径。
CGPathApply   每个元素的图形路径中,调用一个自定义应用功能。
CGPathMoveToPoint   开始在一个可变的图形路径指定一个位置,一个新的子路径。
CGPathCloseSubpath   关闭和一个可变的图形路径完成子路径。
CGPathAddEllipseInRect   添加一个路径,一个适合矩形内的椭圆。

Getting Information about Quartz Paths

CGPathEqualToPath  指示是否两个图形路径是等效的。
CGPathGetBoundingBox  返回包含在图形路径中的所有点的包围盒。
CGPathGetPathBoundingBox   返回图形路径的包围盒
CGPathGetCurrentPoint   返回图形路径中的当前点。
CGPathGetTypeID   返回用于石英图形路径的核心基础类型标识符。
CGPathIsRect     指出是否代表一个矩形图形路径。
CGPathContainsPoint  检查一个点是否包含在图形路径中。
CGLineCap   用于渲染一个行的端点的样式。
CGLineJoin   用于线的连接类型。

苹果官CGPath

CGRectGet系列

CGRectInset(CGRect rect, CGFloat dx, CGFloat dy) dx,dy 是在rect的内部左右,上下距离的值。
CGRectGetHeight返回label本身的高度 
CGRectGetMinY返回label顶部的坐标 
CGRectGetMaxY 返回label底部的坐标
CGRectGetMinX 返回label左边缘的坐标 
CGRectGetMaxX 返回label右边缘的坐标 
CGRectGetMidX表示得到一个frame中心点的X坐标 
CGRectGetMidY表示得到一个frame中心点的Y坐标

根据颜色绘制图片

  -(UIImage *)imageFromColor:(UIColor*)color
  {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context,[color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

值得注意的一点是:

CGContextSaveGState(context);和CGContextRestoreGState(context); 这一对方法的作用是,前者的调用,将会把当前的上下文状态保存在一个“绘图状态栈”中,后者的作用是,将上一次保存在栈中的上下文状态取出,作为当前的上下文状态。这样做的目的,是因为对上下文进行变换会改变上下文整体坐标系,如果在变换上下文前,不进行保存,之后也不恢复的话,再在此上下文绘图,就会按照新的变化后的坐标系绘图,从而发生混乱。

小结

CGContextRefCGMutablePathRef 都是画图工具,但是

  • CGContextRef 可以自己展示出图形
  • CGMutablePathRef 需要与CAShapeLayerCGContextRef配合使用后才可以展示出图形,它只是负责绘制路径path的.

推荐好文章: 打造自己的“美图秀秀” 关于Core Image 看这里


效果.gif

本文考虑到简洁就不上代码了,具体的代码实现的效果可以到我GitHub去下载查看,喜欢的话,请star 一下。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.09.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 简述
    • 让我们来看一下CGContext.h 里面的方法:
      • 让我们来看一下CGPath.h 里面的方法:
        • 小结
        相关产品与服务
        图片处理
        图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档