美文网首页
iOS绘画篇:Quartz2D

iOS绘画篇:Quartz2D

作者: younger_times | 来源:发表于2018-02-12 00:28 被阅读14次

关键步骤:

  • 获取CGContextRef
  • 调用CGContextRef的方法进行绘图

自定义UIView时获取 CGContextRef

开发自定义UIView的方法是,开发一个继承UIView的子类,并重写该UIView的drawRect:方法,当该UIView每次显示出来时,或者内容需要更新时,系统会自动调用UIView的drawRect:方法,在调用drawRect:方法之前,系统会自动配置绘图环境,因此,程序只要通过UIGraphicsGetCurrentContext()

CGContextRef ctx = UIGraphicsGetCurrentContext();

创建位图时获取CGContextRef

如果需要在创建位图时获取CGContextRef,那么程序需要先调用UIGraphicsBeginImageContext(),然后才能调用UIGraphicsGetCurrentContext()获取绘图的CGContextRef

//创建内存中的图片
UIGraphicsBeginImageContext(CGSizeMake(320,480));
//获取向内存中图片执行绘图的CGContextRef
CGContextRef ctx = UIGraphicsGetCurrentContext();

Quartz 2D 绘图的核心API是CGContextRef ,该API并不是一个对象。Quartz 2D本身不是面向对象的,它是面向过程的API。


函数签名 说明
void CGContextClearRect(CGContextRef c,CGRect rect) 擦除指定区域内绘制的图形
void CGContextDrawPath(CGContextRef c. CGPathDraw ingMode mode) 使用指定模式绘制当前路径,第二参数支持: kCGPathFill,kCGPathEOFill,kCGPathStroke, kCGPathFillStroke, kCGPathEOFillStroke
void CGContextEOFillPath(CGContextRef c) 使用奇偶规则来绘制该路径包围的区域,如果某点被包围了奇数次则绘制该点
void CGContextFillPath(CGContextRef c) 填充CGContextRef所包含的路径包围的区域
void CGContextFillRect(CGContextRef c,CGRect rect) 填充矩形路径包含的路径
void CGContextFillRects(CGContextRef c, const CGRect rects [], size tcount) 填充多个矩形
void CGContextFillEllipseInRect(CGContextRef c,CGRect rect) 填充rect矩形内切椭圆的区域
void CGContextStrokePath(CGContextRef c) 使用当前设置的线宽绘制路径
void CGContextStrokeRect(CGContextRef c,CGRect rect) 使用当前设置的线宽绘制矩形路径
void CGContextStrokeRectWithWidth(CGContextRef c,CGRect rect,CGfloat width) 使用指定线宽绘制矩形框
void CGContextReplacePathWithStrokedPath(CGContextRef c) 使用绘制当前路径时覆盖的区域作为当前ref中的新路径
void CGContextStrokeEllipseInRect(CGContextRef c,CGRect rect) 做矩形框内,做椭圆
void CGContextStrokeLineSegments(CGContextRef c,const CGPoint points[], size_count) 使用当前 CGContextRef 设置的线宽绘制多条线段。该方法需要传入 2 N 个 CGPoint 组成的数组,其中第 1-2 个点组成第一条线段,第 3-4 个点组成第二条线段。.... 依此类推

绘图函数

函数签名 说明
void CGContextClearRect(CGContextRef c,CGRect rect) 擦除指定区域内绘制的图形
void CGContextDrawPath(CGContextRef c. CGPathDraw ingMode mode) 使用指定模式绘制当前路径,第二参数支持: kCGPathFill,kCGPathEOFill,kCGPathStroke, kCGPathFillStroke, kCGPathEOFillStroke
void CGContextEOFillPath(CGContextRef c) 使用奇偶规则来绘制该路径包围的区域,如果某点被包围了奇数次则绘制该点
void CGContextFillPath(CGContextRef c) 填充CGContextRef所包含的路径包围的区域
void CGContextFillRect(CGContextRef c,CGRect rect) 填充矩形路径包含的路径
void CGContextFillRects(CGContextRef c, const CGRect rects [], size tcount) 填充多个矩形
void CGContextFillEllipseInRect(CGContextRef c,CGRect rect) 填充rect矩形内切椭圆的区域
void CGContextStrokePath(CGContextRef c) 使用当前设置的线宽绘制路径
void CGContextStrokeRect(CGContextRef c,CGRect rect) 使用当前设置的线宽绘制矩形路径
void CGContextStrokeRectWithWidth(CGContextRef c,CGRect rect,CGfloat width) 使用指定线宽绘制矩形框
void CGContextReplacePathWithStrokedPath(CGContextRef c) 使用绘制当前路径时覆盖的区域作为当前ref中的新路径
void CGContextStrokeEllipseInRect(CGContextRef c,CGRect rect) 做矩形框内,做椭圆
void CGContextStrokeLineSegments(CGContextRef c,const CGPoint points[], size_count) 使用当前 CGContextRef 设置的线宽绘制多条线段。该方法需要传入 2 N 个 CGPoint 组成的数组,其中第 1-2 个点组成第一条线段,第 3-4 个点组成第二条线段。.... 依此类推

表中的大部分函数都涉及使用路径,路径由另一个 API: CGPathRef来代表。CGPathRef 代表任意多条直线或曲线连接而成的任意图形,当 CGContextRef 根据 CGPathRef 绘制时,它可以绘制出任意的形状。

函数 函数说明
void CGContextSaveGState(CGContextRef c) 保存当前绘制的状态,方便恢复
CGContextRestoreGState(CGContextRef c) 回到最近保存的状态
CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef c) 获取当前cgcontextref放大图片时插值质量
void CGContextSetInterpolationQuality(CGContextRef c,CGInterpolationQuality quality) 设置cgcontextref放大图片时插值质量
void CGContextSetLineCap(CGContextRef c,CGLineCap cap) 设置线段端点的绘制形状:kCGLineCapButt 不绘制段点,kCGLineCapRound 圆形端点,kCGLineCapSquare 方形端点
void CGContextSetLineDash(CGContext Ref c. CGF loat phase,Const CGF loat lengths [], size_ tcount) 点线模式 cgflat f= [1,2] 线宽为1 ,间隔为2
void CGContextSetLineJoin(CGContextRef c,CGLineJoin join) 线条连接风格,KCGLineJoinMeter,KCGLineJoinRound,KCGLineJoinBevel
void CGContextSetLineWidth(CGContextRef c,CGFloat width) 绘制直线线条宽度
void CGContextSetMiterLimit(CGContextRef c,CGFloat limit) 控制锐角箭头长度,当把连接点风格设为 meter 风格时,该函数用于控制锐角箭头的长度
void CGContextSetPatternPhase(CGContextRef c, CGSize phase) 采用位图填充相位
void CGContextSetFillPattern(CGContextRef c,CGPatternRef pattern, const CGFloat components []) 使用位图填充
void CGContextSetShouldAntialias(CGContextRef c,bool shouldAntialias) 是否应该抗锯齿
void CGContextSetStrokePattern(CGContextRef c, CGPatternRef pattern,const CGFloat components[]) 使用位图绘制线条,边框
void CGContextSetBlendMode(CGContextRef c, CGBlendMode mode) 叠加模式
void CGContextSetAllowsAntialiasing(CGContextRef c,bool allowsAnitialiasing) 是否允许抗锯齿
void CGContextSetAllowsFontSmoothing(CGContextRef c bool allowsFontSmoothing) 是否使用光滑字体
void CGContextSetShouldSmoothFonts(CGContextRef c,bool shouldSmoonthFonts) 是否应该光滑字体
void CGContextSetAlpha(CGContextRef c,CGFloat alpha) 设置全局透明
void CGContextSetCMYKFillColor(CGContextRef c,CGFloat cyan,CGFloat magenia, CGFloat yellow,CGFloat black,CGFloat alpha) 设置使用cmYK颜色模式来设置填充颜色
void CGContextSetCMYKStrokeColor(CGContextRef c,CGFloat cyan,CGFloat magenia, CGFloat yellow,CGFloat black,CGFloat alpha) 设置使用CMYK颜色模式设置画笔颜色
void CGContextSetFillColorWithColor(CGContextRef c, CGColorRef color) 使用指定颜色来填充颜色
void CGContextSetStrokeColorWithColor(CGContextRef c, CGColorRef color) 设置指定颜色来设置画笔颜色
void CGContextSetGrayFillColor(CGContextRef c,CGFloat gray,CGFloat alpha) 使用灰色来填充颜色
void CGContextSetRGBFillColor(CGContextRef c,CGFloat red,CGFloat green,CGFloat blue,CGFloat alpha) 使用RGB颜色来填充
void CGContextSetRGBStrokeColor(CGContextRef c,CGFloat red,CGFloat green,CGFloat blue,CGFloat alpha) 使用RGB颜色来设置画笔
void CGContextSetShadow(CGContextRef c,CGSize offset,CGFloat blur) 设置阴影在 X、Y方向上的偏移,以及模糊度(blur 值越大,阴影越模糊)。该函数没有设置阴影颜色,默认使用 1/3 透明的黑色(即 RGBA {0,0,O,1.0/3.0})作为阴影颜色
void CGContextSetShadowWithColor(CGContextRef c,CGSize offset,CGFloat blur,CGColorRef color) 设置阴影在 X、Y 方向上的偏移,以及模糊度和阴影的颜色

设置绘图属性的相关函数

函数 函数说明
void CGContextSaveGState(CGContextRef c) 保存当前绘制的状态,方便恢复
CGContextRestoreGState(CGContextRef c) 回到最近保存的状态
CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef c) 获取当前cgcontextref放大图片时插值质量
void CGContextSetInterpolationQuality(CGContextRef c,CGInterpolationQuality quality) 设置cgcontextref放大图片时插值质量
void CGContextSetLineCap(CGContextRef c,CGLineCap cap) 设置线段端点的绘制形状:kCGLineCapButt 不绘制段点,kCGLineCapRound 圆形端点,kCGLineCapSquare 方形端点
void CGContextSetLineDash(CGContext Ref c. CGF loat phase,Const CGF loat lengths [], size_ tcount) 点线模式 cgflat f= [1,2] 线宽为1 ,间隔为2
void CGContextSetLineJoin(CGContextRef c,CGLineJoin join) 线条连接风格,KCGLineJoinMeter,KCGLineJoinRound,KCGLineJoinBevel
void CGContextSetLineWidth(CGContextRef c,CGFloat width) 绘制直线线条宽度
void CGContextSetMiterLimit(CGContextRef c,CGFloat limit) 控制锐角箭头长度,当把连接点风格设为 meter 风格时,该函数用于控制锐角箭头的长度
void CGContextSetPatternPhase(CGContextRef c, CGSize phase) 采用位图填充相位
void CGContextSetFillPattern(CGContextRef c,CGPatternRef pattern, const CGFloat components []) 使用位图填充
void CGContextSetShouldAntialias(CGContextRef c,bool shouldAntialias) 是否应该抗锯齿
void CGContextSetStrokePattern(CGContextRef c, CGPatternRef pattern,const CGFloat components[]) 使用位图绘制线条,边框
void CGContextSetBlendMode(CGContextRef c, CGBlendMode mode) 叠加模式
void CGContextSetAllowsAntialiasing(CGContextRef c,bool allowsAnitialiasing) 是否允许抗锯齿
void CGContextSetAllowsFontSmoothing(CGContextRef c bool allowsFontSmoothing) 是否使用光滑字体
void CGContextSetShouldSmoothFonts(CGContextRef c,bool shouldSmoonthFonts) 是否应该光滑字体
void CGContextSetAlpha(CGContextRef c,CGFloat alpha) 设置全局透明
void CGContextSetCMYKFillColor(CGContextRef c,CGFloat cyan,CGFloat magenia, CGFloat yellow,CGFloat black,CGFloat alpha) 设置使用cmYK颜色模式来设置填充颜色
void CGContextSetCMYKStrokeColor(CGContextRef c,CGFloat cyan,CGFloat magenia, CGFloat yellow,CGFloat black,CGFloat alpha) 设置使用CMYK颜色模式设置画笔颜色
void CGContextSetFillColorWithColor(CGContextRef c, CGColorRef color) 使用指定颜色来填充颜色
void CGContextSetStrokeColorWithColor(CGContextRef c, CGColorRef color) 设置指定颜色来设置画笔颜色
void CGContextSetGrayFillColor(CGContextRef c,CGFloat gray,CGFloat alpha) 使用灰色来填充颜色
void CGContextSetRGBFillColor(CGContextRef c,CGFloat red,CGFloat green,CGFloat blue,CGFloat alpha) 使用RGB颜色来填充
void CGContextSetRGBStrokeColor(CGContextRef c,CGFloat red,CGFloat green,CGFloat blue,CGFloat alpha) 使用RGB颜色来设置画笔
void CGContextSetShadow(CGContextRef c,CGSize offset,CGFloat blur) 设置阴影在 X、Y方向上的偏移,以及模糊度(blur 值越大,阴影越模糊)。该函数没有设置阴影颜色,默认使用 1/3 透明的黑色(即 RGBA {0,0,O,1.0/3.0})作为阴影颜色
void CGContextSetShadowWithColor(CGContextRef c,CGSize offset,CGFloat blur,CGColorRef color) 设置阴影在 X、Y 方向上的偏移,以及模糊度和阴影的颜色
@implementation GeometryView // 重写该方法进行绘图

-(void) drawRect: (CGRect) rect
{

CGContextRef ctx= UIGraphicsGetCurrentContext  () ;//获取绘图上下文
CGContextSetLineWidth  (ctx, 16); // 设置线宽
CGContextSetRGBStrokeColor  (ctx, 0,1, 0,1);
//---------- 下面绘制 3 条线段测试端点形状----------

// 定义 4 个点,绘制线段
const CGPoint points1 [] = {CGPointMake (10, 40),CGPointMake (100 40), CGPointMake (100,40),CGPointMake (20,70) };
CGContextstrokeLineSegments  (ctx, points1, 4); //绘制线段(默认不绘制端点)
CGContextSetLineCap  (ctx, kCGLineCapSquare); //设置线段的端点形状:方形端点
const CGPoint points2  [](CGPointMake (130,40),CGPointMake  (230 40), CGPointMake (230,40),CGPointMake (140,70) }; // 定义 4 个点,绘制线段 
CGContextStrokeLineSegments  (ctx, points2,4); // 绘制线段
CGContextSetLineCap  (ctx, kCGLineCapRound); // 设置线段的端点形状:圆形端点
const CGPoint points3 [] = {CGPointMake (250,40),CGPointMake (350,40), CGPointMake (350,40),CGPointMake (260,70) }; // 定义 4 个点,绘制线段 
CGContextStrokeLineSegments  (ctx, points3,4); // 绘制线段 
// ---------- 下面绘制 3 条线段测试点线模式-----------
CGContextSetLineCap (ctx, kCGLineCapButt); // 设置线段的端点形状
CGContextSetLineWidth  (ctx, 10); // 设置线宽 
CGFloat patterns1 [] = {6,10}; // 设置点线模式:实线宽 6, 间距宽 10 
CGContextSetLineDash  (ctx, 0,patterns1,1); // 定义两个点,绘制线段
const CGPOint points4 [] = {CGPOintMake (40, 85),CGPointMake (280,85) }; 
CGContextStrokeLineSegments  (ctx, points4,2); //绘制线段 
// 设置点线模式:实线宽 6, 间距宽 10, 但第 1 条实线宽 3 
CGContextSetLineDash  (ctx,3,patterns1,1); // 定义两个点,绘制线段 
const CGPOint points5 [] = {CGPointMake (40,105), CGPointMake (280,105) }; 
CGContextStrokeLineSegments  (ctx, points5,2); // 绘制线设
CGFloat patterns2  [] {5,1,4,1,3,1,2,1,1,1,1,2,1,3,1,4,1,5}; 
CGContextSetLineDash  (ctx 0,patterns2,18); // 设置点线模式
const CGPoint points6 [] = {CGPointMake (40,125),CGPointMake (280,125) }; 
CGContextStrokeLineSegments  (ctx, points6,2); // 绘制线段 
/ / -- - -- -- -- 下面填充矩形 - - -------

// 设置线条颜色
CGContextSetStrokeColorWithcolor  (ctx,  [UIColor blueColor]. CGColor); CGContextSetLineWidth  (ctx,14); // 设置线条宽度 
// 设置填充颜色
CGContextSetFillColorWithColor  (ctx, [UIColor redColor]. CGColor);
CGContextFillRect (ctx, CGRectMake (30,140,120,60)); // 填充一个矩形 

// 设置填充颜色
CGContextSetFillColorwithcolor (ctx, [UIColor yellowColor]. CGColor); 
CGContextFillRect  (ctx, CGRectMake  (80 180,120,60));//填充一个矩形 
// - - - - 一 - - - - 下面绘制矩形边框--------
 CGContextSetLineDash  (ctx, C, (),0); // 取消设置点线模式
 // 绘制一个矩形边框
CGContextStrokeRect (ctx, CGRectMake (30,250,120,60));
// 设置线条颜色
CGContextSetStrokeColorWithColor  (ctx,  [UIColor purpleColor]. CGColor); 
CGContextSetLineJoin  (ctx, kCGLineJoinRound); // 设置线条连接点的形状 
// 绘制一个矩形边框
CGContextStrokeRect  (ctx, CGRectMake  (80 280 120 60)); 
CGContextSetRGBStrokeColor(ctx,1.0,0,1.0 1.0)//设置线条颜色
CGContextSetLineJoin  (ctx, kCGLineJoinBevel); // 设置线条连接点的形状
 // 绘制一个矩形边框
CGContextStrokeRect  (ctx, CGRectMake  (130,310,120,60)); 
CGContextSetRGBStrokeColor  (ctx,0,1,1,1); // 设置线条颜色 
/ /--------- 下面绘制和填充一个椭圆--------- 
// 绘制一个椭圆
CGContextStrokeEllipseInRect  (ctx CGRectMake  (30 400 120 60)); 
CGContextSetRGBFillColor (ctx,1,0 1,1); // 设置填充颜色 
// 填充一个椭圆
CGContextEillEllipseInRect (ctx, CGRectMake (180,400,120,60));

点线模式

如果希望使用点线进行绘制,则可调用 CGContextRef 的 CGContextSetLineDash (CGContextRef c, CGFloat phase, const CGFloat lengths [], size_tcount)函数进行设置,该函数的第 3 个参数是点线模式的关键,该参数是一个元素为 CGFloat 类型的数组(第 4 个参数通常用于指定该数组的长度),每个 CGFloat 值依次控制点线的实线长度、间距。比如,该参数设置如下。

  • {2,3}

代表长为 2 的实线、距离为 3 的间距、长为 2 的实线、距离为 3 的间距。... 这种点线模式。

  • {2,3,1}

代表长为 2 的实线、距离为 3 的间距、长为 1 的实线、距离为 2 的间距、长为 3 的实线、距离为 1 的间距。... 这种点线模式。

  • {5,3,1,2}

代表长为 5 的实线、距离为 3 的间距、长为 1 的实线、距离为 2 的间距、长为 5 的实线、距离为 3 的间距、长为 1 的实线、距离为 2 的间距。... 这种点线模式。

绘制文本

函数 说明
CGAffineTransform CGContextGetTextMatrix(CGContextRef c) 获取当前对文本执行变换的变换矩阵
CGPoint CGContextGetTextPosition(CGContextRef c) 获取该CGContextRef当前绘制文本的位置
CGContextSelectFont(CGContextRef c,const char *name,CGFloat size,CGTextEncoding textEncoding) 设置当前文本的字体,字号大小
void CGContextSetCharacterSpacing(CGContextRef c, CGFloat spacing) 设置该文本的字符间距
void CGContextSetFont(CGContextRef c,CGFontRef font) 设置绘制文本字体
void CGContextSetFontSize(CGContextRef c,CGFloat size) 设置文本的字体大小
CGContextSetTextDrawingMode(CGContextRef c,CGTextDrawingMode mode) 设置该CGCcontextRef绘制文本的绘制模式,支持,KCGTextFill,KCGTextStroke,KCGTextFillStroke等
void CGContextSetTextposition() 设置该CGContextRef的一个文本的绘制位置
void CGContextSetTextMatrix (CGContextRef c, CGAffineTransform t) 设置对将要绘制的文本执行指定的变换。
CGContextSetTextPosition (CGContextRef, CGFloat x, CGFloat y) 设置该 CGContextRef 的一个文本的绘制位置。
void CGContextShowText(CGContextRef c,const char *string,size_t length) 控制该CGCcontextRef在当前位置点绘制指定文本
void CGContextShowTextAtPoint(CGContextRefc,CGFloatx,CGFloat y,const char *string ,size_t length) 控制在指定点绘制文本

使用

  • 获取绘图的CGContextRef
  • 设置绘制文本的相关属性
  • 调用NSString drawAtPoint: withArrtibutes:,drawInAttributes:withFont:绘制,如果需要对绘制的文本进行变换,则需要先调用CGContextSetTextMatrix()函数设置变换矩阵,再调用CGContextShowTextAtpoint()
// 重写该方法绘制该控件

- (void) drawRect: (CGRect) rect{

CGContextRef ctx= UIGraphicsGetCurrentContext  ();// 获取该控件的绘图 CGContextRef CGContextSetCharacterSpacing  (ctx, 4); // 设置字符间距
CGContextSetRGBFillColor  (ctx, 1,0,1,1); // 设置填充颜色
 CGContextSetRGBStrokeColor  (ctx, 0, 0,1, 1); // 设置线条颜色 
CGContextSetTextDrawingMode  (ctx, kCGTextFi 11); // 设置使用填充模式绘制文本

 // 绘制文本
 [@“疯狂 i0 s 讲义”drawAtPoint: CGPointMake  (10,20) withAttributes: @ {NSFontAttributeName:  [UIFont fontwithName: @"Arial Rounded MT Bold" size: 45], NSForegroundColorAttributeName:  [UIColor magentaColor] }]; 

// 设置使用描边模式绘制文本
CGContextSetTextDrawingMode  (ctx, kCGTextSt roke);

}

设置阴影

函数 说明
void CGContextSetShadow(CGContextRef c,CGSize offset,CGFloat blur) 设置阴影,x,y方向上的偏移,并设置阴影模糊程度
void CGContextSetShadowWithColor(CGContextRef c,CGSize offset,CGFloat blur,CGColorRef color) 同上,并增加阴影颜色
CGContextRef ctx = UIGraphicsGetCurrentContext  (); // 获取绘图的 CGContextRef 
// 使用默认的阴影颜色,阴影向右上角投影,模糊度为 5 
CGContextSetShadow  (ctx, CGSizeMake (8, -6), 5); 
CGContextSetRGBFillColor  (ctx, 1,0, 1,1); // 设置填充颜色 CGContextSetRGBStrokeColor  (ctx,0, 0,1, 1); 
// 设置线条颜色 CGContextSetTextDrawingMode  (ctx, kCGTextFill);
 // 设置使用填充模式绘制文本 // 绘制文本
[@“疯狂 iOS 讲义“drawAtPoint: CGPointMake  (10,20) withAttributes: @ {NSFontAttributeName: [UIFont fontWithName: @"Arial Rounded MT Bold" size: 45],NSForegroundColorAttributeName:  [UIColor magentacolor] }];

使用路径

函数 说明
void CGContextBeginPath(CGContextRef c) 开始定义路径
void CGContextClosePath(CGContextRef c) 关闭前面定义的路径
void CGContextAddArc(CGContextRef c,CGFloat x,CGFloat y,CGFloat radius,CGFloat startAngle ,CGFloat endAngle,int clockwise) 当前路径添加一段弧
void CGContextAddArcToPoint(CGContextRef c,CGFloat x1,CGFloat y1,CGFloat x2,CGFloat y2,CGFloat radius) 和上面差不多,只是弧定义不一样
CGContextAddCurveToPoint(CGContextRef c,CGFloat cp1x,CGFloat cp1y,CGFloat cp2x,CGFloat cp2y,CGFloat x,CGFloat y) 当前路径添加一条贝济埃曲线
void CGContextAddLines(CGContextRef c,const CGPoint points[],size_t count) 当前路径添加多条线段,1-2个点组成第一个线段,第2-3个点组成第二个线段
void CGContextAddLineToPoint(CGContextRef c,CGFloat x,CGFloat y) 当前路径从结束点连接到x,y
void CGContextAddQuadCurveToPoint(CGContextRef c,CGFloat cpx,CGFloat cpy,CGFloat x,CGFloat y) 当前路径添加一条二次曲线
void CGContextAddRect(CGContextRef c, CGRect rect) 当前路径添加一条矩形
void CGContextMoveToPoint(CGContextRef c,CGFloat x,CGFloat y) 结束点移动到x,y
void CGContextAddllipselnRcc CGContextRef context, CGRect rect) 向 CGContextRef 的当前路径添加一个椭圆
void CGPathRef CGContextCopyPath (CGCont context) 复制当前 CGContextRef 包含的路径,该函数返回的CGPathRef 代表了当前 CGContextRef 包含的路径
void CGContextAddPath (CGContextRef context, CGPathRef path) 将已有的 CGPathRef 代表的路径添加到当前CGContextRef 的路径中
  • CGContextIsPathEmpty(CGContextRef c) 该函数用于判断指定CGContextRef包含的路径是否为空

  • CGPoint CGContextGetPathCurrentPoint (GContextR c) 该函数用于返回指定 CGContextRef 包含的路径的当前点。

  • CGContextGetPathBoundingBox(CGCcontextRef c)该函数用于返回指定CGContextRef中能完整保卫所有路径的最小矩形

  • CGContextPathContainsPoint该函数判断指定CGContextRef包含的路径按指定绘制模式进行绘制时,是否需要绘制point点

  • 调用CGCcontextBeginPath开始定义路径

  • 调用以上添加子路径

  • 如果路径添加完成,则调用CGContextClosePath关闭路径

  • 调用CGContextDrawPath,CGContextEOFillPath,CGContextFillPath,CGContextStrokePath函数来填充路径

    • KCGPathFill: 指定填充路径
    • KCGPathEOFill: 指定采用even-odd模式填充路径。
    • KCGPathStroke: 指定只绘制路径
    • KCGPathFillStroke: 指定既绘制路径,也填充路径
    • KCGPathEOFillStroke: 指定既绘制路径,也采用even-odd模式填充路径

绘制曲线

函数 说明
CGContextAddCurveToPoint(CGContextRef c,float cpx1,float cpy1,float cpx2,float cpy2,float x, float y) 添加曲线,贝济埃曲线
CGContextAddQuadCurveToPoint(CGContextRef c,float cpx,float cpy,float x,float y) 二次添加
  • CGContextAddCurveToPoint 负责从路径的当前点,作为开始点,到结束点(x,y)的贝济埃曲线,其中cpx1,cpy1作为第一个控制点的坐标,cpx2,cpy2 作为第二个控制点的坐标。

  • CGContextAddQuadCurveToPoint 复制绘制从路径的当前点,到结束点(x,y)的二次曲线,其中cpx,cpy定义控制点的坐标。

CGContextMoveToPoint  (c, dx, dy + size); // 移动到指定点 
CGFloat dig = 2 *M_PI n; // 采用循环添加 n 段二次曲线路径 
for (int i= 1; i <n+1; i++)
{
// 计算控制点坐标
CGFloat ctrlX = sin  ((i- 0.5) * dig) length + dx;
CGFloat ctrlY= cos ((i 一 0.5) * dig) length + dy;

// 计算结束点坐标
CGFloat x = sin  (i * dig) * size + dx;
CGFloat y =cos  (i * dig) size + dy;
// 添加二次曲线路径
CGContextAddQuadCurveToPoint  (c,ctr1 X ctrlY y);
}

在内存中绘图

有过介绍,都是通过扩展UIView ,重写drawRect:方法进行绘图时,这种绘图方式是直接在UIView控件上绘制所有图形,由于每次该空间显示出来时,drawRect:方法都会被调用,这意味着每次该控件显示出来时,程序都需要重绘所有图形。

UIGraphicsBeginImageContext(CGSize size)该函数用于准备绘图环境。调用UIGraphicsEndImageContext()函数结束绘图和关闭绘图环境。

  1. 调用UIGraphicsBeginImageContext(CGSize size)函数准备绘图环境
  2. 调用UIGraphicsGetCurrentContext函数获取绘图CGContextRef
  3. 使用签名介绍的绘制集合图形,使用路径等方式进行绘图
  4. 调用UIGraphicsGetImageFromCurrentImageContext()函数获取当前绘制的图形,该函数返回一个UIImage对象
  5. 调用UIGraphicsEndImageContext()函数结束绘图,并关闭绘图环境
  • UIRectFill(CGRect rect)向当前绘图环境所创建的内存中的图片上填充一个矩形
  • UIRectFillUsingBlendMode(CGRect rect,CGBlendMode blendMode) 向当前绘图环境所创建的内存中的图片上填充一个矩形,绘制时使用指定的混合模式。
  • UIRectFrame(CGRect rect) 向当前绘图环境所创建的内存中的图片上绘制一个矩形边框
  • UIRectFrameUsingBlendMode(CGRect rect,CGBlendMode blendMode)向当前绘图环境所创建的内存中的图片上绘制一个矩形边框,绘制时使用指定的混合模式
UIGraphicsBeginImageContext  (size); // 创建内存中的图片绘制环境
CGContextRef ctx = UIGraphicsGetCurrentContext();
//todo
UIGraphicsEndImageContext  ();
// 保存 PNG 图片
[UI ImagePNGRepresentation  (newImage) writeToFile: path atomically: YES];

绘制位图

为了绘制位图,UIImage 本身已经提供了如下方法

  • drawAtPoint:将该图片本身绘制到当前绘图CGContextRef的指定点。调用该方法必须传入一个CGPoint 参数,指定该图片的绘制点。
  • drawAtPoint:blendMode:alpha:属于前一个方法的增强版,它可以指定绘制图片的叠加模式和透明度。
  • drawInRect将该图片本身绘制到当前绘图CGContextRef的指定区域内,调用该方法必须传入一个CGRect参数,指定该图片的绘制区域
  • drawInRect: blendMode: alpha:属于前一个方法的增强版,它可以指定绘制图片的叠加模式和透明度。
  • CGContextDrawImage该函数用于将Image绘制到rect区域内
  • CGContextDrawTiledImage该函数采用‘平铺’模式将image绘制到rect区域内。
  • CGImageCreateCopy 该函数将会创建image图片的副本
  • CGImageCreateWithImageInRect该函数将挖取image图片中的rect区域
// 将窗口的 layer 图片渲染到当前绘图上下文中
 [screenWindow. layer renderInContext: UIGraphicsGetCurrentContext  ()];
// 调用 CALayer 的方法将当前控件绘制到绘图 Context 中
[targetView. Layer renderInContext: context];

图形变换

  • CGContextTranslateCTM

平移坐标系统,该函数相当于把原来位于(0,0) 位置的坐标原点平移到(tx, ty)点。在平移后的坐标系统上绘制图形时,所有坐标点的 X 坐标都相当于增加了 tx,所有点的 Y 坐标都相当于增加了 ty。

  • CGContextScaleCTM

缩放坐标系统,函数控制坐标系统水平方向上缩放 sx,垂直方向上缩放 sy。在缩放后的坐标系统上绘制图形时,所有点的 X 坐标都相当于乘以 SX 因子,所有点的 Y 坐标都相当于乘以 sy 因子。

  • CGContextRotateCTM

旋转坐标系统,坐标系统旋转 angle 弧度。在旋转后的坐标系统上绘制图形时,所有坐标点的 X、Y 坐标都相当于旋转了 angle 弧度之后的坐标。

提供以下两个函数保存,恢复绘图状态
CGContextSaveGState 保存当前的绘图状态
CGContextRestoreGState恢复之前保存的绘图状态

使用矩阵变换

  • CGContextConcatCTM

使用transform变换矩阵对CGContextRef的坐标系统执行变换,通过使用坐标矩形可以对坐标系统执行任意变换

  • CGContextGetCTM

获取CGContextRef的坐标系统的变换矩阵

前面介绍的 CGContextRotateCTM()、CGContextScaleCTM()、CGContextTranslateCTM()三个坐标变换函数其实都可通过 CGContextConcatCTM()函数来实现,只是通过 CGContextConcatCTM() 函数进行坐标变换比较复杂。

创建CGAffineTransform

  • CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)

创建进行位移的变换矩阵。

  • CGAffineTransformMakeScale(CGFloat sx,CGFloat sy)

创建进行缩放变换的变换矩阵

  • CGAffineTransformMakeRotation(CGFloat angle)

创建进行旋转变换的变换矩阵

  • CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c,CGFloat d, CGFloat tx, CGFloat ty)

该函数使用自定义变换矩阵执行变换

  • CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx,CGFloat ty)

对已有的变换矩阵t额外增加位移变换

  • CGAffineTransformScale(CGAffineTransform t, CGFloat sx,CGFloat sy)

对已有的变换矩阵t额外增加缩放变换

  • CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)

对已有的变换矩阵t额外增加旋转变换

  • CGAffineTransformInVert(CGAffineTransform t)对已有的变换矩阵t进行反转
  • CGAffineTransformConcat(CGAffineTransform t1,CGAffineTransform, t2)

将两个变换矩阵进行叠加

  • CGPointApplyAffineTransform(CGPoint point,CGAffineTransform t)

对指定的CGPoint执行变换,函数返回坐标变换后的CGPoint

  • CGSizeApplyAffineTransform(CGSize size,CGAffineTransform t)

对指定的CGSize执行变换,函数返回坐标变换后的CGSize

  • CGRectApplyAffineTransform(CGRect rect,CGAffineTransform t)

对指定的CGRect执行变换,函数返回坐标变换后的CGRect

控制叠加模式

默认情况下,后面绘制的图形将会完全覆盖在前面绘制的图形。在特定情况下,可能会需要其他的叠加风格

  • CGContextSetBlendMode(CGContextRef context,CGBlendMode mode)

设置该CGContextRef 绘图环境的叠加模式

处理填充

渐变填充

  • CGContextDrawLinearGradient

设置线性渐变填充,gradient参数代表渐变对象,startPoint参数设置线性渐变的开始点,endPoint参数设置线性渐变的结束点

  • CGContextDrawRadialGradient

设置圆形渐变填充 ,gradient参数代表渐变对象,startCenter参数设置起始圆的圆心,startRadius参数设置起始圆
的半径 endCenter参数设置结束圆的圆心,endRedius参数设置结束圆的半径

获取CGGradientRef 可调用以下函数

  • CGGradientCreateWithColorComponents

space用于指定该渐变所使用的颜色空间(RGB,CMYK,GRay等)locations指定各颜色点的分布位置,count参数指定该渐变包含多少种颜色

相关文章

网友评论

      本文标题:iOS绘画篇:Quartz2D

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