CG系统方法

2018-07-27  本文已影响13人  SamCheck
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);
上一篇下一篇

猜你喜欢

热点阅读