CG系统方法

UIKit底层框架.png

方法解析

图形上下文栈

/* 保存CGContextRef当前的绘图状态,方便以后恢复该状态。*/
void CGContextSaveGState(CGContextRef c);
/*把CGContextRef的状态恢复到最近一次保存时的状态*/
void CGContextRestoreGState(CGContextRef c);

矩阵操作

void CGContextScaleCTM(CGContextRef c,CGFloat sx,CGFloat sy);

功能:缩放
sx:水平方向上的缩放。所有点的 X 坐标都相当于乘以 sx 因子。
sy:垂直方向上的缩放。所有点的 Y 坐标都相当于乘以 sy因子。

void CGContextRotateCTM(CGContextRef c,CGFloat angle);

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

void CGContextTranslateCTM(CGContextRef c,CGFloat tx,CGFloat ty);

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

void CGContextConcatCTM(CGContextRef c, CGAffineTransform transform);

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

/* 获取CGContextRef的坐标系统的变换矩阵*/
CGAffineTransform CGContextGetCTM(CGContextRef c);

图形上下文状态

typedef CF_ENUM(int32_t, CGLineJoin) {
    kCGLineJoinMiter,// 默认
    kCGLineJoinRound,// 圆角
    kCGLineJoinBevel// 切角
};
/*设置线条连接点的风格,该属性支持如上三个值:*/
void CGContextSetLineJoin(CGContextRef c, CGLineJoin join);

typedef CF_ENUM(int32_t, CGLineCap) {
    kCGLineCapButt,//默认
    kCGLineCapRound,//圆角
    kCGLineCapSquare //会比默认的样式两边各多一个线宽/2的距离
};
/*设置线段端点的绘制形状*/
void CGContextSetLineCap(CGContextRef c, CGLineCap cap);

/*设置绘制直线、边框时的线条宽度*/
void CGContextSetLineWidth(CGContextRef c, CGFloat width);

/*当把连接点风格设为meter风格时,该方法用于控制锐角箭头的长度*/
void CGContextSetMiterLimit(CGContextRef c, CGFloat limit);

/*设置全局透明度*/
void CGContextSetAlpha(CGContextRef__nullable c, CGFloat alpha);

/*设置CGContextRef的叠加模式。Quartz 2D支持多种叠加模*/
void CGContextSetBlendMode(CGContextRef __nullable c,CGBlendMode mode);

图形上下文-虚线

void CGContextSetLineDash(CGContextRef c, CGFloat phase,const CGFloat * lengths, size_t count);

phase:指定虚线模式的起始点。
lengths:指明虚线是如何交替绘制,{10, 20, 10}:则表示先绘制10个点,跳过20个点,绘制10个点,跳过10个点,再绘制20个点,如此反复
count: lengths数组的长度

可以做条形码.png

图形上下文-实线

/*开始一个新的子路径点*/
void CGContextMoveToPoint(CGContextRef__nullable c,CGFloat x, CGFloat y);

/* 添加一条直线段从当前指向的(x,y)。 */
void CGContextAddLineToPoint(CGContextRef__nullable c,CGFloat x, CGFloat y);

图形上下文-贝塞尔曲线

/**
 *  从当前添加一个三次Bezier曲线
 *  @param cp1x 控制点1 x坐标
 *  @param cp1y 控制点1 y坐标
 *  @param cp2x 控制点2 x坐标
 *  @param cp2y 控制点2 y坐标
 *  @param x    直线的终点 x坐标
 *  @param y    直线的终点 y坐标
 */
void CGContextAddCurveToPoint(CGContextRef__nullable c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y);

/**
 *  从当前添加一个二次Bezier曲线
 *  @param cpx 控制点 x坐标
 *  @param cpy 控制点 y坐标
 *  @param x   直线的终点 x坐标
 *  @param y   直线的终点 y坐标
 */
void CGContextAddQuadCurveToPoint(CGContextRef__nullable c, CGFloat cpx, CGFloat cpy,CGFloat x,CGFloat y);
贝塞尔曲线.png

图形上下文-矩形

void CGContextAddRect(CGContextRef c,CGRect rect);
void CGContextAddRects(CGContextRef c,const CGRect * rects, size_t count);
void CGContextStrokeRect(CGContextRef c, CGRect rect);
void CGContextFillRect(CGContextRef c, CGRect rect);

图形上下文-圆形、椭圆

void CGContextAddEllipseInRect(CGContextRef__nullable c, CGRect rect);

图形上下文-弧形

/**
 *  添加弧形对象
 *  @param x          中心点x坐标
 *  @param y          中心点y坐标
 *  @param radius     半径
 *  @param startAngle 起始弧度
 *  @param endAngle   终止弧度
 *  @param clockwise  是否逆时针绘制,0则顺时针绘制
 */
void CGContextAddArc(CGContextRef__nullable c, CGFloat x,CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle,int clockwise);
圆形角度.png
/*三次贝塞尔曲线创建一个弧*/
void CGContextAddArcToPoint(CGContextRef__nullable c, CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2, CGFloat radius);

举个栗子:

CGContextMoveToPoint(context,150,350);//圆弧的起始点
CGContextAddArcToPoint(context,100,380,130,450,40);

从起点:(150,350)(100,380)划线。
从起点:(150,350)(130,450)划线。
从两线的夹角,画一个半径为40的圆,圆和两夹角线相切。

画圆弧.png
角度计算

图形上下文-路径

/*添加路径到图形上下文*/
void CGContextAddPath(CGContextRef c,CGPathRef path);

/*关闭路径-让路径成为一个闭环*/
void CGContextClosePath(CGContextRef cg_c);

/*判断当前路径有没有指定的点*/
bool CGContextPathContainsPoint(CGContextRef cg_nullable c,CGPoint point, CGPathDrawingMode mode);

图形上下文-填充
kCGPathFill:只有填充(非零缠绕数填充),不绘制边框。图1
kCGPathEOFill:奇偶规则填充(多条路径交叉时,奇数交叉填充,偶交叉不填充)。图2
kCGPathStroke:只有边框。图3
kCGPathFillStroke:既有边框又有填充。图4
kCGPathEOFillStroke:奇偶填充并绘制边框。图5

填充示例
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
  kCGPathFill,
  kCGPathEOFill,
  kCGPathStroke,
  kCGPathFillStroke,
  kCGPathEOFillStroke
};
/*使用指定模式绘制当前CGContextRef中所包含的路径*/
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode);

/*填充该路径包围的区域*/
void CGContextFillPath(CGContextRef__nullable c);

/*使用奇偶规则来填充该路径包围的区域。奇偶规则指:如果某个点被路径包围了奇数次,系统绘制该点;如果被路径包围了偶数次,系统不绘制*/
void CGContextEOFillPath(CGContextRef__nullable c);

/*使用当前 CGContextRef设置的线宽绘制路径*/
void CGContextStrokePath(CGContextRef__nullable c);

/*填充rect代表的矩形*/
void CGContextFillRect(CGContextRef__nullable c, CGRect rect);

/*填充多个矩形*/
void CGContextFillRects(CGContextRef__nullable c,const CGRect * __nullable rects, size_t count);

/*使用当前 CGContextRef设置的线宽绘制矩形框*/
void CGContextStrokeRect(CGContextRef__nullable c, CGRect rect);

/*使用指定线宽绘制矩形框*/
void CGContextStrokeRectWithWidth(CGContextRef__nullable c,CGRect rect, CGFloat width);

/*擦除指定矩形区域上绘制的图形*/
void CGContextClearRect(CGContextRef__nullable c, CGRect rect);

/*填充rect矩形的内切椭圆区域*/
void CGContextFillEllipseInRect(CGContextRef__nullable c,CGRect rect);

/*使用当前 CGContextRef设置的线宽绘制rect矩形的内切椭圆*/
void CGContextStrokeEllipseInRect(CGContextRef__nullable c, CGRect rect);

图形上下文-裁剪

/* 剪切指定矩形区域外的部分. */
void CGContextClipToRect(CGContextRef c, CGRect rect);

/* 剪切指定多个矩形区域外的部分 */
void CGContextClipToRects(CGContextRef c,const CGRect *  rects, size_t count);

/* 修改当前剪贴路径,使用非零绕数规则。 */
void CGContextClip(CGContextRef c);

/* 修改当前剪贴路径,使用奇偶规则。 */
void CGContextEOClip(CGContextRef c);

/*  剪切遮罩处理(针对图片)-使用图片作为遮罩*/
void CGContextClipToMask(CGContextRef c, CGRect rect, CGImageRef mask);

/* 获取到了需要绘制的图形上下文的位置与大小*/
CGRect CGContextGetClipBoundingBox(CGContextRef c);

CGRect clips[] =
        {
            CGRectMake(110.0, 0, 35.0, 100.0),
            CGRectMake(165.0, 0, 35.0, 100.0),
        };
CGContextClipToRects(context, clips, sizeof(clips) / sizeof(clips[0]));
CGContextDrawImage(context, CGRectMake(110.0, 0, 100.0, 100.0), image);
CGContextClipToRects

图形上下文-颜色

/* 使用指定颜色来设置该CGContextRef的填充颜色*/
void CGContextSetFillColorWithColor(CGContextRef c,CGColorRef color);

/* 使用指定颜色来设置该CGContextRef的线条颜色*/
void CGContextSetStrokeColorWithColor(CGContextRef c,CGColorRef color);

图形上下文-图片

/*绘制图像到图形上下文中 */
void CGContextDrawImage(CGContextRef c, CGRect rect,CGImageRef  image);

/*绘制图像到图形上下文中 */
void CGContextDrawImage(CGContextRef c, CGRect rect,CGImageRef  image);

/*重复绘制的图像,扩展到提供的矩形,填补当前剪辑区域。 */
void CGContextDrawTiledImage(CGContextRef c, CGRect rect,CGImageRef  image);

/*获取当前CGContextRef在放大图片时的插值质量*/
CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef c);

/*设置图形上下文的插值质量水平。*/
void CGContextSetInterpolationQuality(CGContextRef c,CGInterpolationQuality quality);
typedef CF_ENUM (int32_t, CGInterpolationQuality) {
  kCGInterpolationDefault = 0,  /* Let the context decide. */
  kCGInterpolationNone = 1,     /* Never interpolate. */
  kCGInterpolationLow = 2,      /* Low quality, fast interpolation. */
  kCGInterpolationMedium = 4,   /* Medium quality, slower than kCGInterpolationLow. */
  kCGInterpolationHigh = 3      /* Highest quality, slower than kCGInterpolationMedium. */
};

图形上下文-设置阴影

/*设置阴影在X、Y方向上的偏移,以及模糊度和阴影的颜色*/
void CGContextSetShadowWithColor(CGContextRef c,CGSize offset, CGFloat blur, CGColorRef  color);

/*设置阴影在X、Y方向上的偏移,以及模糊度(blur值越大,阴影越模糊)。该函数没有设置阴影颜色,默认使用1/3透明的黑色(即RGBA{0, 0, 0, 1.0/3.0})作为阴影颜色*/
void CGContextSetShadow(CGContextRef c, CGSize offset,CGFloat blur);

图形上下文-渐变、阴影遮罩

/* 绘制一个渐变填充定义的出发点和落脚点沿线变化。*/
void CGContextDrawLinearGradient(CGContextRef c,CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,CGGradientDrawingOptions options);

/* 绘制一个沿着由所提供的开始和结束的圆限定的区域变化的渐变填充。 */
void CGContextDrawRadialGradient(CGContextRef c,CGGradientRef gradient, CGPoint startCenter, CGFloat startRadius,CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions options);

/* 使用指定的阴影的背景,填充剪切路径。 */
void CGContextDrawShading(CGContextRef c, CGShadingRef shading);
typedef CF_OPTIONS (uint32_t, CGGradientDrawingOptions) {
  kCGGradientDrawsBeforeStartLocation = (1 << 0),
  kCGGradientDrawsAfterEndLocation = (1 << 1)
};

图形上下文-PDF操作

/* 绘制一个PDF页面到当前的用户空间。 */
void CGContextDrawPDFPage(CGContextRef c,CGPDFPageRef  page);

/* 基于页面的图形上下文中开始了新的一页。 */
void CGContextBeginPage(CGContextRef c,const CGRect * mediaBox);

/* 在基于页面的图形上下文结束当前的页面。 */
void CGContextEndPage(CGContextRef c);

图形上下文-透明层

void CGContextBeginTransparencyLayer(CGContextRef c,CFDictionaryRef auxiliaryInfo);

/* 开始透明度层,它的边界是指定的矩形,其内容是有界的。 */
void CGContextBeginTransparencyLayerWithRect(CGContextRef c, CGRect rect, CFDictionaryRef auxInfo);

/* 结束一个透明层。 */
void CGContextEndTransparencyLayer(CGContextRef c);

透明层(TransparencyLayers)通过组合两个或多个对象来生成一个组合图形。组合图形被看成是单一对象。当需要在一组对象上使用特效时,透明层非常有用。

举个栗子:

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGSize myShadowOffset = CGSizeMake (10, -20);
    CGContextSetShadow (ctx, myShadowOffset, 10);
    
    CGContextBeginTransparencyLayer (ctx, NULL);
    CGContextSetRGBFillColor (ctx, 0, 1, 0, 1);
    CGContextFillRect (ctx, CGRectMake (10,100,50,50));
    CGContextSetRGBFillColor (ctx, 0, 0, 1, 1);
    CGContextFillRect (ctx, CGRectMake (10 + 25,100 + 25,50,50));
    CGContextSetRGBFillColor (ctx, 1, 0, 0, 1);
    CGContextFillRect (ctx, CGRectMake (10+ 25+ 25,100+ 25+ 25,50,50));
    CGContextEndTransparencyLayer (ctx);
透明层

//设置CoreText绘制前的坐标。设置基线位置
CG_EXTERN void CGContextSetTextPosition(CGContextRef cg_nullable c,CGFloat x, CGFloat y);

CG_EXTERN CGPoint CGContextGetTextPosition(CGContextRef cg_nullable c);
//设置当前文本矩阵
CG_EXTERN void CGContextSetTextMatrix(CGContextRef cg_nullable c,CGAffineTransform t);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容

  • 原文出处 http://blog.csdn.net/u014286994/article/details/5133...
    Poison_19ce阅读 1,431评论 0 2
  • canvas元素的基础知识 在页面上放置一个canvas元素,就相当于在页面上放置了一块画布,可以在其中进行图形的...
    oWSQo阅读 10,257评论 0 19
  • 缩放坐标系统:该方法控制坐标系统水平方向上缩放 sx,垂直方向上缩放 sy。在缩放后的坐标系统上绘制图形时,所有点...
    ElliotYamin阅读 1,210评论 0 10
  • Quartz2D以及drawRect的重绘机制字数1487 阅读21 评论1 喜欢1一、什么是Quartz2D Q...
    PurpleWind阅读 757评论 0 3
  • 基础 核心动画是 iOS 和 MacOS 上的图形渲染和动画基础结构,用于为应用的视图和其他视觉元素设置动画。 核...
    davon阅读 1,873评论 0 8