zoukankan      html  css  js  c++  java
  • CGContextRef&CGMutablePathRef&UIBezierPath简单学习

    简单的四句介绍

    Quartz是一个二维绘图引擎,使用的是CoreGraphics库,同时支持iOS和Mac系统

    CGContextRef:获取图形上下文.或者叫作用域,即画布,他是专门用来保存绘画期间的各种数据的

    UIBezierPath是对CGPathRef的封装。创建矢量图形时,拆解成一条或者多条线段,拼接起来,每条下端的终点都是下一条线段的起点

    当我们绘制路径时,Path的信息就会被Graphics context重置。 如果我们想要保存path信息,并多次使用它,我们就可以用到CGPathCreatMutable申请路径,然后用CGPathAddLintToPoint等方法来添加路径。

    一起学习,共同进步,可下载对应Demo

    1.设置点和线

    介绍属性

    • 先设置一个起点
    • 添加一个中间点
    • 画一个矩形
    • 画一个圆形
    • 画一个扇形
    • 二阶曲线
    • 三阶曲线
    CGContextRefUIBezierPathCGMutablePathRef
    CGContextMoveToPoint moveToPoint CGPathMoveToPoint
    CGContextAddLineToPoint addLineToPoint CGPathAddRect
    CGContextAddRect bezierPathWithRect CGPathAddRect
    CGContextAddEllipseInRect bezierPathWithOvalInRect CGPathAddEllipseInRect
    CGContextAddArc addArcWithCenter CGPathAddArcToPoint
    CGContextAddQuadCurveToPoint addQuadCurveToPoint CGPathAddQuadCurveToPoint
    CGContextAddCurveToPoint addCurveToPoint CGPathAddCurveToPoint

    2、设置线的属性

    这些设置线属性的API都是通用的

    • 线宽 CGContextSetLineWidth
    • 线的颜色 CGContextSetStrokeColorWithColor
    • 填充颜色 CGContextSetFillColorWithColor
    • line join CGContextSetLineCap
    • line cap CGContextSetLineJoin
    • 透明度 CGContextSetAlpha
    • 设置阴影 CGContextSetShadow
    • 设置阴影颜色 CGContextSetShadowWithColor
    • 切割操作 CGContextClip

    思维导图

            

     

    CGContextRef介绍

    Quartz2d是一个二维绘图引擎,使用的是CoreGraphics库,同时支持iOS和Mac系统

    有点难,比较底层,操作系统层api一般都是纯C开发的,有针对性的开发才会用到

    要基于UIView去开发

    实战用途

    画线段

    • 画直线CGContextAddLineToPoint

    • 画虚线CGContextSetLineDash

    画三角形

    • CGContextClosePath

    画矩形

    • CGContextAddRect

    画圆

    • CGContextAddEllipseInRect

    画扇形

    • CGContextAddArc

    画曲线

    • CGContextAddQuadCurveToPoint

    • CGContextAddCurveToPoint

    画特效

    • CGContextSetShadow

    • CGContextSetAlpha

    绘制文字

    • drawInRect

    绘制图片

    • drawInRect

    • CGContextClip

    变换运用(改变画布位置)

    • CGContextTranslateCTM

    • CGContextRotateCTM

    • CGContextScaleCTM


    1、CGContextRef之画线段
    CGContextRef 具有贯穿全局的效果,我们设置一个全局变量创建 一次 就可以了

    虚线
    - (void)drawLine1{
        //获取图形上下文.或者叫作用域,即画布,他是专门用来保存绘画期间的各种数据的
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        //路径设置
        //先设置一个起点
        CGContextMoveToPoint(contextRef, 50, 100);
        //设置终点
        CGContextAddLineToPoint(contextRef, 100, 500);
        
        //设置样式
        //设置线宽
        CGContextSetLineWidth(contextRef, 5.0f);
        //设置线的颜色
        CGContextSetStrokeColorWithColor(contextRef, [UIColor redColor].CGColor);
        
        //风格  头部和尾部的处理
        CGContextSetLineCap(contextRef, kCGLineCapRound);
        
        
        /*
         画虚线
         参数1 作用域
         参数2 起点的偏移量
         参数3 指明虚线是如何交替绘制
         lengths的值{10,10}表示先绘制10个点,再跳过10个点
         如果把lengths值改为{10, 20, 10},则表示先绘制10个点,跳过20个点,绘制10个点,跳过10个点,再绘制20个点,
         参数4 实心部分和虚心部分的循环次数
         */
        CGFloat lenths[] = {10, 10};
        CGContextSetLineDash(contextRef, 0, lenths, 2);
        
        
        //渲染
        CGContextStrokePath(contextRef);
    }
    

     效果图

                  

    2、CGContextRef之画多边形

    画三角形

    - (void)drawTriangle{
        //获取图形上下文
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        //设置点
        CGContextMoveToPoint(contextRef, 100, 100);
        CGContextAddLineToPoint(contextRef, 200, 200);
        CGContextAddLineToPoint(contextRef, 100, 200);
        
        //把点封闭起来
        CGContextClosePath(contextRef);
        
        //设置线宽
        CGContextSetLineWidth(contextRef, 3.0f);
        //设置线的颜色
        CGContextSetStrokeColorWithColor(contextRef, [UIColor redColor].CGColor);
        //设置填充颜色
        CGContextSetFillColorWithColor(contextRef, [UIColor greenColor].CGColor);
        
        
        // 如果写了多种渲染方式,那么只执行第一种
    //    CGContextStrokePath(contextRef);
    //    CGContextFillPath(contextRef);
        
        CGContextDrawPath(contextRef, kCGPathFillStroke);
     
    }
    

     效果图

    画正方形

    //获取图形上下文
       CGContextRef contextRef = UIGraphicsGetCurrentContext();
       
       CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));
       
       //颜色的填充
       CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
       //线宽
       CGContextSetLineWidth(contextRef, 4.0f);
       CGContextSetStrokeColorWithColor(contextRef, [UIColor blueColor].CGColor);
       
       //渲染
       CGContextDrawPath(contextRef, kCGPathFillStroke);
    

     效果图

    3、CGContextRef之画曲线

    画圆

     // 绘制图形上下文
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        CGContextAddEllipseInRect(contextRef, CGRectMake(100, 100, 100, 100));
        
        CGContextDrawPath(contextRef, kCGPathFillStroke);
    

     扇形

    - (void)drawArc1{
        
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        /*
         参数1:作用域
         参数2:圆心x坐标
         参数3:圆心y坐标
         参数4:半径
         参数5:开始角度
         参数6:结束角度
         参数7:方向,0表示顺时针,1表示逆时针
         
         */
        CGContextAddArc(contextRef, 100, 200, 100, 0, M_PI_4, 0);
        
        CGContextSetLineWidth(contextRef, 5.0f);
        CGContextSetFillColorWithColor(contextRef, [UIColor greenColor].CGColor);
        CGContextSetStrokeColorWithColor(contextRef, [UIColor redColor].CGColor);
        
        
    //    CGContextAddLineToPoint(contextRef, 100, 200);
        
        CGContextDrawPath(contextRef, kCGPathFillStroke);
        
        
    }
    
    
    
    
    - (void)drawArc2{
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        
        //第一部分
        CGContextMoveToPoint(contextRef, 250, 400);
        CGContextAddArc(contextRef, 250, 400, 100, 0, M_PI_2, 0);
        CGContextSetFillColorWithColor(contextRef, [UIColor blueColor].CGColor);
        CGContextFillPath(contextRef);
        
        
        //第二部分
        CGContextMoveToPoint(contextRef, 250, 400);
        CGContextAddArc(contextRef, 250, 400, 100, M_PI_2, M_PI_2/2*3, 0);
        CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
        CGContextFillPath(contextRef);
        
        // 第三部分
        CGContextMoveToPoint(contextRef, 250, 400);
        CGContextAddArc(contextRef, 250, 400, 100, 0, 225*M_PI/180.0, 1);
        CGContextSetFillColorWithColor(contextRef, [UIColor purpleColor].CGColor);
        CGContextFillPath(contextRef);
    
        
    }
    

     效果图

    画曲线

       
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        //起点
        CGContextMoveToPoint(contextRef, 20, 300);
        /*
         三阶贝塞尔曲线
         参数1:作用域
         参数2:控制点x
         参数3:控制点y
         参数4:控制点x
         参数5:控制点y
         参数6:终点x
         参数7:终点y
         
         - `CGContextAddQuadCurveToPoint`  二阶贝塞尔曲线
         */
        CGContextAddCurveToPoint(contextRef, 100, -100, 200, 900, 300, 400);
         CGContextStrokePath(contextRef);    
    

     效果图

    4、CGContextRef之画特效
     CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        
        CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));
        CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
        CGContextSetStrokeColorWithColor(contextRef, [UIColor greenColor].CGColor);
        CGContextSetLineWidth(contextRef, 5.0f);
        
        //设置透明度
        //取值范围(0~1,0表示全透明,1是不透明)
         CGContextSetAlpha(contextRef, 1);
        
        /*
         设置阴影
         参数1:画布
         参数2:右偏移量
         参数3:下偏移量
         参数4:模糊度(0是不模糊,越大越模糊,10就差不多)
         */
        CGContextSetShadow(contextRef, CGSizeMake(10, 10), 10);
        
        
        CGContextDrawPath(contextRef, kCGPathFillStroke);
    

     效果图

    5、CGContextRef之绘制
    绘制文字
     NSDictionary *dic = @{
                              NSFontAttributeName:[UIFont systemFontOfSize:15],
                               NSForegroundColorAttributeName : [UIColor redColor]
                              };
        // 两种的区别drawInRect会自动换行,drawAtPoint:CGPointZero不会自动换行
        [text drawInRect:CGRectMake(20, 100, self.bounds.size.width - 40, 100) withAttributes:dic];
    //    [text drawAtPoint:CGPointMake(20, 200) withAttributes:dic];
    

     绘制图片

    - (void)drawImage{
        UIImage *image = [UIImage imageNamed:@"image.jpg"];
        [image drawInRect:CGRectMake(100, 100, 250, 250)];
        // 平铺图像,超出部分会自动剪裁
    //    [image drawAsPatternInRect:self.bounds];
        // 如果实现文字和图片共存,需要将文字写在后面,防止被图片盖住
        NSDictionary *dic = @{
                              NSFontAttributeName:[UIFont systemFontOfSize:15],
                              NSForegroundColorAttributeName : [UIColor redColor]
                              };
        NSString *text = @"如果实现文字和图片共存,需要将文字写在后面,防止被图片盖住";
        [text drawInRect:CGRectMake(100, 300, 250, 100) withAttributes:dic];
    }
    
    -(void)clipImage{
        /*
         思路:先画一个圆,让图片显示在圆的内部,超出的部分不显示。
         注意:显示的范围只限于指定的剪切范围,无论往上下文中绘制什么东西,只要超出了这个范围的都不会显示。
         */
        
        
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        // 先画一个圆形
        CGContextAddEllipseInRect(contextRef, CGRectMake(100, 400, 200, 200));
        
        // 切割操作
        CGContextClip(contextRef);
        CGContextFillPath(contextRef);
        
        
        UIImage *image = [UIImage imageNamed:@"image.jpg"];
        [image drawInRect:CGRectMake(100, 400, 200, 200)];
        
    
    }
    

     效果图

    6、CGContextRef之图形变换
     UIImage *image0 = [UIImage imageNamed:@"image.jpg"];
        [image0 drawInRect:CGRectMake(300, 400, 100, 100)];
        
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        // 移动变换
        //    CGContextTranslateCTM(contextRef, -100, -100);
        /**
         *  对象沿着x轴移动-100单位,沿着y轴移动-100单位
         */
        // 多个变换会叠加
        // 缩放
        //    CGContextScaleCTM(contextRef, 0.5, 0.5);
        
        // 获取中心点
    //    CGFloat cenX = CGRectGetMidX(self.bounds);
    //    CGFloat cenY = CGRectGetMidY(self.bounds);
    //    
        
        // 先移动一下
        //    CGContextTranslateCTM(contextRef, cenX, cenY);
        CGContextTranslateCTM(contextRef, 100+100/2.0, 100+100/2.0);
        
        // 旋转变换
        CGContextRotateCTM(contextRef, M_PI_4);
        // 再移动回去
        CGContextTranslateCTM(contextRef, -(100+100/2.0), -(100+100/2.0));
        
        /**
         *  旋转可以认为实质是旋转坐标系,会绕着坐标原点旋转,可以先将坐标原点移动到要旋转的图形的中点,然后执行旋转,然后再移动回来,实现绕着图形中心旋转的目的
         */
        
        
        UIImage *image = [UIImage imageNamed:@"image.jpg"];
        [image drawInRect:CGRectMake(300, 400, 100, 100)];
    

     效果图

    UIBezierPath

    使用步骤

    • 创建一个 UIBezierPath 对象

    • 用 moveToPoint: 设置初始线段的起点

    • 添加线段,定义一或多个子路径

    • 修改 UIBezierPath 的绘图相关的属性,比如stroke path的属性 lineWidth 和 lineJoinStyle , filled path的属性 usesEvenOddFillRule

    常用API
    • 创建矩形bezierPathWithRect

    • 创建矩形内切圆bezierPathWithOvalInRect

    • 圆角矩形bezierPathWithRoundedRect

    • 创建弧形bezierPathWithArcCenter

    • 添加直线addLineToPoint

    • 添加弧形线段addArcWithCenter

    • 添加二阶贝塞尔曲线addQuadCurveToPoint

    • 添加三阶贝塞尔曲线addCurveToPoint

    参考链接
    Quartz 2D学习(一)简单绘制图形
    iOS的UIBezierPath类和贝塞尔曲线

    https://www.jianshu.com/p/5e39624efa26

  • 相关阅读:
    Coding styles, code review
    Some links haven't take a look(C++, JS, IE9)
    前端学习,找到一下一些问题的答案
    Browser judgement
    Theme of Google
    Browser Time Line
    迷茫在10点左右……
    WebPageTest 检测web站点性能网站测试工具
    Invoke IFrame/window in cross domain in IE&FF notes
    [解决]多线程中出现由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达
  • 原文地址:https://www.cnblogs.com/GJ-ios/p/10955804.html
Copyright © 2011-2022 走看看