• Quartz2D--iOS下的图形绘制


    一、基本介绍

    Quartz 2D是一个二维绘图引擎,Quartz 2DAPIC语言,来自CoreGraphics框架,没有面向对象的思想。

     1.作用:绘制图形:线条、三角形、矩形、圆、弧等

     绘制文字

     绘制、生成图片(图形)

     读取、生成PDF

     截图、裁剪图片

     自定义UI控件

     2.图形上下文(Graphics Context:是一个CGContextRef类型的数据

     

     图形上下文的作用:1.保存绘图信息、绘图状态

     2.决定绘制的输出目标(绘制到什么地方,输出目标可以是PDF文件、Bitmap或者显示器的窗口上)

     

    二、Quartz 2D基本图形绘制

    1.线段、矩形、三角形的绘制

    新建工程,新建 DrawLine 类继承UIView,在storyboard拖拽一个View,关联DrawLine类,在DrawLine中实现图形绘制代码

     

      1 #import "DrawLine.h"
      2 
      3 @implementation DrawLine
      4 
      5 
      6 // Only override drawRect: if you perform custom drawing.
      7 // An empty implementation adversely affects performance during animation.
      8 
      9 
     10 //系统自动调用 drawRect 方法,当视图显示在屏幕上的时候调用,并且只会被调用一次
     11 //而当它的内容需要更新的时候,也会被调用,那个调用需要通过setNeedsDisplayInRect
     12 - (void)drawRect:(CGRect)rect {
     13 
     14     //画一条线段
     15     drawline();
     16     
     17     //画两条线段
     18     drawline2();
     19     
     20     //画矩形
     21     drawR();
     22     
     23     //画三角形
     24     drawTriangle();
     25     
     26 }
     27 
     28 
     29 /** Quartz 2D的API是C语言,所以要用C的ff */
     30 
     31 //画线
     32 
     33 //画一条线段
     34 void drawline(){
     35     //1.获得图形上下文
     36     CGContextRef context = UIGraphicsGetCurrentContext();
     37     
     38     //2.绘制图形
     39     
     40     //2.1 设置线段的宽度
     41     //参数1:图形上下文
     42     //参数2:宽度
     43     CGContextSetLineWidth(context, 10);
     44     
     45     //2.2 设置线条的颜色
     46     //空心的颜色
     47     CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
     48     
     49     //2.3 设置起点
     50     //参数1:图形上下文
     51     //参数2:起点x坐标
     52     //参数3:起点y坐标
     53     CGContextMoveToPoint(context, 10, 10);
     54     
     55     //画线(添加线条)
     56     CGContextAddLineToPoint(context, 100, 100);
     57     
     58     //3.将绘制的图形显示到View上
     59     //以空心的方式画出
     60     CGContextStrokePath(context);
     61 }
     62 
     63 //画两条线段
     64 void drawline2(){
     65     //获得图形上下文
     66     CGContextRef context = UIGraphicsGetCurrentContext();
     67     
     68     //设置线段的宽度
     69     //参数1:图形上下文
     70     //参数2:宽度
     71     CGContextSetLineWidth(context, 10);
     72 
     73     
     74     //2条线条
     75     [[UIColor blueColor] set];
     76     
     77     //设置线条头尾部的样式
     78     //参数2:头尾部的样式
     79     //kCGLineCapButt,线条头尾部比较大
     80     //kCGLineCapRound,线条头尾部圆形
     81     //kCGLineCapSquare,线条头尾部是方形
     82     CGContextSetLineCap(context, kCGLineCapRound);
     83     
     84     //设置线段转折点样式
     85     //参数2:转折点样式
     86     //kCGLineJoinMiter,
     87     //kCGLineJoinRound,
     88     //kCGLineJoinBevel
     89     CGContextSetLineJoin(context, kCGLineJoinRound);
     90     
     91     //设置起点
     92     CGContextMoveToPoint(context, 100, 100);
     93     //画线(添加线条)
     94     CGContextAddLineToPoint(context, 150, 120);
     95     CGContextAddLineToPoint(context, 150, 180);
     96     CGContextStrokePath(context);
     97 }
     98 
     99 //画矩形,系统提供了方法
    100 void drawR(){
    101     //1.获得图形上下文
    102     CGContextRef context = UIGraphicsGetCurrentContext();
    103     
    104     //2.绘制四边形
    105     //参数1:图形上下文
    106     //参数2:CGRect rect
    107     CGContextAddRect(context,  CGRectMake(200, 30, 120, 180));//这个系统提供的绘制四边形的方法,四边形的边会与x,y轴平行。我们可以通过旋转View,或者用CGContextAddLineToPoint方法自定义
    108     
    109     //设置颜色
    110     [[UIColor purpleColor] setFill];//实心颜色
    111     
    112     //3.显示在View上
    113     CGContextFillPath(context);//实心图案
    114 }
    115 
    116 
    117 //画三角形
    118 void drawTriangle(){
    119     //1.获取图形上下文
    120     CGContextRef context = UIGraphicsGetCurrentContext();
    121     
    122     //2.绘制三角形
    123     //确定起点
    124     CGContextMoveToPoint(context, 0, 0);
    125     //添加线条
    126     CGContextAddLineToPoint(context, 100, 100);
    127     CGContextAddLineToPoint(context, 150, 100);
    128     
    129     //调用系统提供的方法关闭路径
    130     CGContextClosePath(context);
    131     
    132     //设置一下颜色
    133     [[UIColor yellowColor] set];
    134     
    135     //显示到view上
    136     CGContextStrokePath(context);
    137     
    138 }
    139 
    140 
    141 @end

    以上代码输出样式:

    另外利用图形上下文栈,可以控制线条的样式,代码如下:

     1 //画一条线段
     2 void drawline(){
     3     //1.获得图形上下文
     4     CGContextRef context = UIGraphicsGetCurrentContext();
     5     
     6     //将上下文拷贝一份放到栈中
     7     CGContextSaveGState(context);
     8     
     9     //2.绘制图形
    10     //第1条线
    11     //2.1 设置线段的宽度
    12     //参数1:图形上下文
    13     //参数2:宽度
    14     CGContextSetLineWidth(context, 20);
    15     
    16     //设置线条头尾部的样式
    17     CGContextSetLineCap(context, kCGLineCapRound);
    18     
    19     //2.2 设置线条的颜色
    20     //空心的颜色
    21     CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
    22     
    23     //2.3 设置起点
    24     //参数1:图形上下文
    25     //参数2:起点x坐标
    26     //参数3:起点y坐标
    27     CGContextMoveToPoint(context, 10, 10);
    28     
    29     //画线(添加线条)
    30     CGContextAddLineToPoint(context, 100, 100);
    31     
    32     //3.将绘制的图形显示到View上
    33     //以空心的方式画出
    34     CGContextStrokePath(context);
    35     
    36     //将图形上下文出栈,替换当前的上下文
    37     CGContextRestoreGState(context);
    38     
    39     //2条线条
    40     [[UIColor blueColor] set];
    41     
    42     //设置线条头尾部的样式
    43     //参数2:头尾部的样式
    44     //kCGLineCapButt,线条头尾部比较大
    45     //kCGLineCapRound,线条头尾部圆形
    46     //kCGLineCapSquare,线条头尾部是方形
    47     CGContextSetLineCap(context, kCGLineCapRound);
    48     
    49     //设置线段转折点样式
    50     //参数2:转折点样式
    51     //kCGLineJoinMiter,
    52     //kCGLineJoinRound,
    53     //kCGLineJoinBevel
    54     CGContextSetLineJoin(context, kCGLineJoinRound);
    55     
    56     //设置起点
    57     CGContextMoveToPoint(context, 120, 120);
    58     //画线(添加线条)
    59     CGContextAddLineToPoint(context, 150, 120);
    60     CGContextAddLineToPoint(context, 150, 180);
    61     CGContextStrokePath(context);
    62 }

    图片效果:

     

     

     

     

     

     

    2.圆形、弧形、文字、图片的绘制

    新建一个类 DrawCircle 继承 UIView ,把storyboard里的View关联该类,然后实现代码

     

      1 #import "DrawCircle.h"
      2 
      3 //求弧度的方法
      4 CGFloat arc(CGFloat angle){
      5     return angle * (M_PI / 180);
      6 }
      7 
      8 @implementation DrawCircle
      9 
     10 
     11 - (void)drawRect:(CGRect)rect {
     12 
     13     //圆形
     14     drawCircle();
     15     
     16     //画圆弧
     17     drawArc();
     18     
     19     //文字
     20     drawText();
     21     
     22     //图片
     23     //绘制图片
     24     drawImg();
     25 }
     26 
     27 //圆形
     28 void drawCircle(){
     29     //1.获取图形上下文
     30     CGContextRef context = UIGraphicsGetCurrentContext();
     31     
     32     //2.绘制图形
     33     //系统画椭圆的方法,如果把宽度和高度设为一样就是圆形了
     34     //参数1:图形上下文
     35     //参数2:CGRect rect
     36     CGContextAddEllipseInRect(context, CGRectMake(50, 50, 80, 100));
     37     //设置线条的宽度
     38     CGContextSetLineWidth(context, 5);
     39     //3.显示在View上
     40     CGContextStrokePath(context);
     41     
     42 }
     43 
     44 //弧形
     45 void drawArc(){
     46     //1.获取图形上下文
     47     CGContextRef context = UIGraphicsGetCurrentContext();
     48     
     49     //2.绘制图形
     50     //系统提供画圆弧的方法
     51     //参数1:图形上下文
     52     //参数2:圆心所在的x坐标
     53     //参数3:圆心所在的y坐标
     54     //参数4:半径
     55     //参数5:开始的角度
     56     //参数6:结束的角度
     57     //参数7:旋转方向,1-->顺时针,0-->逆时针
     58     CGContextAddArc(context, 150, 150, 50, arc(0), arc(90), 0);
     59     
     60     //3.显示
     61     CGContextFillPath(context);
     62 }
     63 
     64 //绘制文字
     65 void drawText(){
     66     
     67     NSString * str = @"绘制文字";
     68     
     69     NSMutableDictionary * attributes = [NSMutableDictionary dictionary];
     70     attributes[NSFontAttributeName] = [UIFont systemFontOfSize:20];//设置文字大小
     71     attributes[NSForegroundColorAttributeName] = [UIColor purpleColor];//设置文字的颜色
     72    
     73     //在这里中,绘制文字的方法是直接调用OC中的方法,所以不需要获得图形上下文,直接调用
     74     //参数1:文字的位置和宽高
     75     //参数2:字典
     76     [str drawInRect:CGRectMake(200, 100, 100, 100) withAttributes:attributes];
     77 
     78 }
     79 
     80 //绘制图片
     81 void drawImg(){
     82     //1.因为绘制图片也是调用OC的方法,所以不需要拿到图形上下文,只需要拿到图片即可
     83     //取得图片
     84     UIImage * img = [UIImage imageNamed:@"广州.png"];
     85     
     86     //2.画图片
     87     [img drawAtPoint:CGPointMake(5, 300)];//在哪个点画图片
     88     
     89     //3.该方法规定了图片的高度和宽度
     90 //    img drawInRect:CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)
     91     
     92     //4.这个方法规定了 按图片高度和宽度来使用填充
     93 //    img drawAsPatternInRect:CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)
     94     
     95     //在图片上绘制文字,即水印
     96     NSString * str = @"广州";
     97     [str drawInRect:CGRectMake(10, 300, 100, 40) withAttributes:nil];
     98 }
     99 
    100 
    101 
    102 @end

    运行效果:

    3.补充:贝塞尔曲线

    贝塞尔曲线:是由线段和节点构成的,它的节点是可以移动的,线段就像橡皮筋一样随着节点和变化

    示例代码:

     1 //贝塞尔曲线:是由线段和节点构成的,它的节点是可以移动的,线段就像橡皮筋一样随着节点和变化
     2 void drawBezier(){
     3     //1.取得图形上下文
     4     CGContextRef context = UIGraphicsGetCurrentContext();
     5     
     6     //贝塞尔曲线有四个节点,一个起点,一个终点,还有两个控制点
     7     
     8     //设置起点
     9     CGContextMoveToPoint(context, 10, 10);
    10     
    11     //添加2个控制点
    12     //参数1:图形上下文
    13     //参数2:第一个控制点的x坐标
    14     //参数3:第一个控制点的y坐标
    15     //参数4:第二个控制点的x坐标
    16     //参数5:第二个控制点的y坐标
    17     //参数6:终点的x坐标
    18     //参数7:终点的y坐标
    19     CGContextAddCurveToPoint(context, 120, 100, 180, 50, 190, 190);
    20     
    21     //系统中还有一个方法添加1个控制点
    22     //参数1:图形上下文
    23     //参数2:第一个控制点的x坐标
    24     //参数3:第一个控制点的y坐标
    25     //参数4:终点的x坐标
    26     //参数5:终点的y坐标
    27 //    CGContextAddQuadCurveToPoint(context, 150, 200, 200, 100);
    28     
    29     //显示到View上
    30     CGContextStrokePath(context);
    31 }

    运行效果:

    三、使用Quartz 2D绘制小黄人

    在storyboard中的View关联创建的 DrawHuman 类,实现代码

      1 #import "DrawHuman.h"
      2 
      3 //半径
      4 #define JKRadius 70
      5 //Y坐标
      6 #define JKTopY 100
      7 //颜色
      8 #define JKColor(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
      9 
     10 @implementation DrawHuman
     11 
     12 
     13 // Only override drawRect: if you perform custom drawing.
     14 // An empty implementation adversely affects performance during animation.
     15 - (void)drawRect:(CGRect)rect {
     16 
     17     //1.图形上下文
     18     CGContextRef context = UIGraphicsGetCurrentContext();
     19     
     20     //画身体
     21     drawBody(context,rect);
     22     
     23     //画嘴巴
     24     drawMouse(context,rect);
     25     
     26     //画眼睛
     27     drawEyes(context,rect);
     28 }
     29 
     30 //画身体
     31 void drawBody(CGContextRef context,CGRect rect){
     32     //1.上半圆的画法
     33     CGFloat topX = rect.size.width * 0.5;
     34     CGFloat topY = JKTopY;
     35     CGFloat topRadius = JKRadius;
     36     //圆心坐标,topX,topY
     37     //半径,topRadius
     38     //开始角度,0
     39     //结束角度,M_PI
     40     //方向,1顺时针
     41     CGContextAddArc(context, topX, topY, topRadius, 0, M_PI , 1);
     42     
     43 
     44     //2.向下延伸 的直线
     45     CGFloat middleX = topX - topRadius;//向下延伸的X坐标
     46     CGFloat middleH = JKTopY;//向下延伸的高度
     47     CGFloat middleY = JKTopY + 100;//Y轴的高度
     48     //添加一条直线
     49     CGContextAddLineToPoint(context, middleX, middleY);
     50     
     51 
     52     //3.下半圆
     53     CGFloat bottomX = topX;
     54     CGFloat bottomY = middleY;
     55     CGFloat bottomRadius = topRadius;
     56     CGContextAddArc(context, bottomX, bottomY, bottomRadius, M_PI, 0, 1);
     57     
     58     //合并路径
     59     CGContextClosePath(context);
     60 
     61     
     62     //设置颜色
     63     [JKColor(252,218,0) set];
     64     
     65     //显示在View上
     66     CGContextFillPath(context);
     67 }
     68 
     69 //画嘴巴
     70 void drawMouse(CGContextRef context,CGRect rect){
     71     //设置一个控制点
     72     CGFloat controlX = rect.size.width * 0.5;
     73     CGFloat controlY = rect.size.height * 0.3;
     74     
     75     //设置当前点
     76     // x y 轴的距离
     77     CGFloat marginX = 20;
     78     CGFloat marginY = 10;
     79     //当前点,即贝塞尔曲线的起点位置
     80     CGFloat currentX = controlX - marginX;
     81     CGFloat currentY = controlY - marginY;
     82     CGContextMoveToPoint(context, currentX, currentY);
     83     
     84     //结束点
     85     CGFloat endX = controlX + marginX;
     86     CGFloat endY = currentY;
     87     
     88     //贝塞尔曲线
     89     CGContextAddQuadCurveToPoint(context, controlX, controlY, endX, endY);
     90     
     91     //设置颜色
     92     [[UIColor blackColor] set];
     93     
     94     //显示到View上
     95     CGContextStrokePath(context);
     96 }
     97 
     98 //画眼睛
     99 void drawEyes(CGContextRef context,CGRect rect){
    100     
    101     //1.黑色绑带
    102     CGFloat startX = rect.size.width * 0.5 - JKRadius;
    103     CGFloat startY = JKTopY;
    104     //将线段移动到起点
    105     CGContextMoveToPoint(context, startX, startY);
    106     
    107     //设置终点的值
    108     CGFloat endx = startX + 2*JKRadius;
    109     CGFloat endY = JKTopY;
    110     
    111     //画线
    112     CGContextAddLineToPoint(context, endx, endY);
    113     CGContextSetLineWidth(context, 15);
    114     [[UIColor blackColor] set];
    115     
    116     //显示到View上
    117     CGContextStrokePath(context);
    118     
    119     //灰色镜框
    120     [JKColor(61,62,66) set];
    121     CGFloat kuangRadius = JKRadius * 0.4;
    122     CGFloat kuangY = startY;
    123     CGFloat kuangX = rect.size.width * 0.5 - kuangRadius;
    124     CGContextAddArc(context, kuangX + 25, kuangY, kuangRadius, 0, M_PI * 2, 0);
    125     CGContextFillPath(context);
    126     
    127     //里面的白色框
    128     [[UIColor whiteColor] set];
    129     CGFloat whiteRadius = kuangRadius * 0.7;
    130     CGFloat whiteY = kuangY;
    131     CGFloat whiteX = kuangX;
    132     CGContextAddArc(context, whiteX + 25, whiteY, whiteRadius, 0, M_PI * 2, 0);
    133     CGContextFillPath(context);
    134     
    135     //眼睛
    136     [[UIColor blackColor]set];
    137     CGFloat blackRadius = whiteRadius * 0.5;
    138     CGFloat blackX = whiteX;
    139     CGFloat blackY = whiteY;
    140     CGContextAddArc(context, blackX + 25, blackY, blackRadius, 0, M_PI * 2, 0);
    141     CGContextFillPath(context);
    142     
    143 }
    144 
    145 
    146 @end

    运行效果:

     

     

  • 相关阅读:
    扩展json序列化datatime类型数据
    用select实现socket的IO多路复用
    Python单例模式
    Django(信号相关)
    将字符串按固定长度分隔成子串
    Android Handler介绍
    Android activity生命周期
    Java 启动线程的方式
    java线程中的sleep和wait区别
    JAVA 统计字符串中中文,英文,数字,空格的个数
  • 原文地址:https://www.cnblogs.com/HOYF/p/5429033.html
Copyright © 2020-2023  润新知