前言
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 里面的类文件众多:
让我们来看一下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 里面的方法:
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 用于线的连接类型。
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);
这一对方法的作用是,前者的调用,将会把当前的上下文状态保存在一个“绘图状态栈”中,后者的作用是,将上一次保存在栈中的上下文状态取出,作为当前的上下文状态。这样做的目的,是因为对上下文进行变换会改变上下文整体坐标系,如果在变换上下文前,不进行保存,之后也不恢复的话,再在此上下文绘图,就会按照新的变化后的坐标系绘图,从而发生混乱。
小结
CGContextRef 与 CGMutablePathRef 都是画图工具,但是
- CGContextRef 可以自己展示出图形
- CGMutablePathRef 需要与CAShapeLayer或CGContextRef配合使用后才可以展示出图形,它只是负责绘制路径path的.
推荐好文章:
打造自己的“美图秀秀”
关于Core Image 看这里
本文考虑到简洁就不上代码了,具体的代码实现的效果可以到我GitHub去下载查看,喜欢的话,请star 一下。