美文网首页程序员
iOS QuartZ 2D 窥探

iOS QuartZ 2D 窥探

作者: 小草毋正 | 来源:发表于2017-12-18 11:17 被阅读0次

    QuartZ 2D

    demo地址

    本demo是由本人通过学习,看前辈们的博客看文档和自己学习的一个小总结,只用于学习使用,其中难避免有一些错误(如果发现了希望能指正),以及引用一些前辈总结出来的东西(如果内容为禁止引用请指出,小弟马上删除),所以此Demo仅供学习参考,不作为权威学习资料。

    适用于:本人自己总结笔记, 对QuarZ 2D初步了解,作为笔记使用

    本Demo只对一般的画图形以及基本图形操作进行一般总结

    quraz2d.png

    目录

    QuartZ2D简介

    QuartZ 2D(Core Graphics)是一个二维绘制引擎,同时支持iOS和Mac系统。它提供低级别、轻量级、高保真的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱贫渲染、模板、渐变。

    可以完成的工作

    • 绘制图形:线条\三角形\矩形\圆\弧 等
    • 绘制文字
    • 绘制\生成图片
    • 读取\生成PDF
    • 截图\裁剪图片

    QuartZ2D开发中的作用

    • 绘制一些系统没有的图形,比如折线图
    • 自定义控件

    图形上下文

    图形上下文(CGContextRef)相当于画板,用于分钟绘画信息绘画状态和输出。

    类型

    • Bitmap Graphics Context
    • PDF Graphics Context
    • Window Graphics Context
    • Layer Context
    • Post Graphics Context

    DrawRect

    UIView的显示

    UIView的显示过程

    1.当UIView需要显示时,内部的层会准备好一个CGConextRef(图形上下文)然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法
    2平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

    UIView的显示原理

    1既使不导入QuartzCore框架,NSObject和UIView类中的-drawLayer:inContext:方法,也是存在的,只是没有代码提示而已.
    2默认情况下,根图层的delegate就是根图层所在的UIView对象,只不过是弱引用.
    @property(assign) id delegate;
    3当UIView需要显示时,它内部的view.layer图层会准备好一个CGContextRef关联到图层设备,然后调用view.layer.delegate代理(就是view)的(原生的)-drawLayer:inContext:方法.

    绘图步骤

    直接绘画

    1.获取当前控件图形上下文
    2.描述绘画内容
    3.设置绘画上下文状态
    4.渲染图形上下文

    // 1.获取图形上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 2.直接绘制内容
    CGContextMoveToPoint(context, 50, 50); // 移动到一个点
    CGContextAddLineToPoint(context, 200, 50); // 画直线
    
    //3. 设置属性
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); // 设置画笔颜色
    CGContextSetLineWidth(context, 5); // 设置线宽
    
    // 4.渲染
    CGContextStrokePath(context);
    
    format_context.png

    通过添加路径(等)绘制

    1.获取当前控件图形上下文
    2.创建路径,描绘路径(CGPath, UIBezierPath)
    3.把路径添加到上下文中
    4.设置上下文状态
    5.渲染上下文

    // 1.获取当前山下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 2.创建路径,描绘路径
    CGMutablePathRef path = CGPathCreateMutable();
    
    CGPathMoveToPoint(path, NULL, 10, 50); //移动到(10, 50)
    CGPathAddLineToPoint(path, NULL, 300, 50); //画一条直线到(300, 50)
    
    CGPathMoveToPoint(path, NULL, 10, 80); //移动到(10, 80)
    CGPathAddLineToPoint(path, NULL, 300, 80); //画一条直线到(300, 80)
    
    CGPathAddRect(path, NULL, CGRectMake(10, 100, 200, 200)); //画一个矩形(10, 100, 200, 200)
    
    //3.把路径添加到上下文中
    CGContextAddPath(context, path);
    //4.设置上下文状态
    [[UIColor redColor] set]; // 设置颜色
    CGContextSetLineWidth(context, 10); //设置线宽
    CGContextSetLineCap(context, kCGLineCapRound); //设置线终点样式
    CGContextSetLineJoin(context, kCGLineJoinRound);//设置线拐角样式
    
    //5.渲染
    CGContextStrokePath(context);
    
    //释放CGMutablePathRef
    CGPathRelease(path);
    
    format_addPath.png

    通过UIBezierPath绘图

    提示:
    1.UIKit已经封装了一些绘图的功能:UIBezierPath,里面封装了很多东西,可以帮我画一些基本的线段,矩形,圆等等,一般开发中用贝塞尔路径绘图。
    2.CGPath转换:UIKit框架转CoreGraphics直接 .CGPath 就能转换

    绘制过程:
    1.创建Bezier路径
    2.绘制bezier路径
    3.设置bezier状态
    4.绘制路径

    //1.获取UIBezierPath
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    //2. 画一个圆 参数分别是: 圆心,半径,开始弧度,结束弧度,顺时针
    [path addArcWithCenter:self.center radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
    
    //3.设置状态
    [[UIColor blueColor] set]; //设置颜色
    [path setLineWidth:5]; //设置线宽
    
    //4.渲染
    [path stroke];
    
    format_bezier.png

    画图形

    直线

    // 获取行下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    float width = self.bounds.size.width; //宽度
    float heiht = self.bounds.size.height; //高度
    float distance = 40; //间距
    
    float beginY = 10; //开始的Y坐标
    float beginX = 10; //开始的X坐标
    
    //横线
    NSInteger countOfX = (heiht - beginY)/distance;
    for(NSInteger index = 0; index <= countOfX; index ++){
    float Y = beginY + index * distance;
    CGPoint begin = CGPointMake(beginX, Y);
    CGPoint end   = CGPointMake(width, Y);
    
    CGContextMoveToPoint(context, begin.x, begin.y);
    CGContextAddLineToPoint(context, end.x, end.y);
    }
    
    //竖线
    NSInteger countOfY = (width - beginX)/distance;
    for(NSInteger index = 0; index <= countOfY; index ++){
    float X = beginX + index * distance;
    CGPoint begin = CGPointMake(X, beginY);
    CGPoint end   = CGPointMake(X, heiht);
    
    CGContextMoveToPoint(context, begin.x, begin.y);
    CGContextAddLineToPoint(context, end.x, end.y);
    }
    
    // 设置属性
    [[UIColor blueColor] set];
    CGContextSetLineWidth(context, 0.5);
    
    // 渲染
    CGContextStrokePath(context);
    
    graphical_lines.png

    三角形

    // 三角形的三个点
    CGPoint point1 = CGPointMake(160, 100);
    CGPoint point2 = CGPointMake(10,  300);
    CGPoint point3 = CGPointMake(320, 300);
    
    // 绘制点
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:point1];
    [path addLineToPoint:point2];
    [path addLineToPoint:point3];
    [path addLineToPoint:point1];
    
    // 设置样式
    [[UIColor redColor] set];
    [path setLineWidth:10];
    [path setLineJoinStyle:kCGLineJoinRound];
    
    // 渲染
    [path stroke];
    
    graphical_triangle.png

    矩形

    //1.获取上下文
    CGContextRef context  = UIGraphicsGetCurrentContext();
    
    //2.画第一个矩形
    CGContextAddRect(context, CGRectMake(50, 50, 100, 100));
    [UIColor redColor];
    CGContextStrokePath(context);
    
    //3.画第二个矩形
    CGContextAddRect(context, CGRectMake(50, 200, 200, 200));
    [[UIColor blueColor] set];
    CGContextSetLineWidth(context, 5);
    CGContextStrokePath(context);
    
    graphical_rect.png

    椭圆

    //1.获取上下文
    CGContextRef context  = UIGraphicsGetCurrentContext();
    //第一个椭圆(圆)
    CGContextAddEllipseInRect(context, CGRectMake(50, 50, 200, 200));
    [[UIColor redColor] set];
    CGContextSetLineWidth(context, 5);
    CGContextStrokePath(context);
    //第二个圆(椭圆)
    CGContextAddEllipseInRect(context, CGRectMake(50, 300, 300, 200));
    [[UIColor blueColor] set];
    CGContextSetLineWidth(context, 10);
    CGContextStrokePath(context);
    
    graphical_ellipse.png

    圆弧

    CGContextRef context  = UIGraphicsGetCurrentContext();
    // 参数依次是: 上下文,圆心x, 圆心y, 半径, 开始弧度, 结束弧度, 逆时针方向
    CGContextAddArc(context, 200, 200, 90, M_PI_2, M_PI, YES);
    CGContextStrokePath(context);
    //第二个圆弧
    CGContextMoveToPoint(context, 200, 400);
    CGContextAddArc(context, 200, 400, 90, 0, M_PI_2, YES);
    CGContextAddLineToPoint(context, 200, 400);
    [[UIColor grayColor] set];
    CGContextFillPath(context);
    
    graphical_arc.png

    曲线

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 200)];
    //第一段曲线 参数:到的点,控制点(具体查看赛贝尔线)
    [path addQuadCurveToPoint:CGPointMake(self.bounds.size.width * 0.5, 200) controlPoint:CGPointMake(self.bounds.size.width * 0.25, 150)];
    //第二段曲线
    [path addQuadCurveToPoint:CGPointMake(self.bounds.size.width, 200) controlPoint:CGPointMake(self.bounds.size.width * 0.75, 250)];
    [[UIColor redColor] set];
    [path setLineWidth:2];
    [path stroke];
    
    graphical_curve.png

    图片处理

    水印

    /** 图片加水印 */
    + (UIImage *)imageName:(NSString *)imageName logoImageName:(NSString *)logoImageName {
        UIImage *image = [UIImage imageNamed:imageName];
        // 开始Image上下文
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
        //画主图
        [image drawAtPoint:CGPointZero]; //
        //画log图
        UIImage *logoImage = [UIImage imageNamed:logoImageName];
        [logoImage drawInRect:CGRectMake(image.size.width - 100, image.size.height - 100, 100, 100)];
        //获取合成图
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndPDFContext();
        return newImage;
    }
    
    image_logo.png

    剪切

    /** 图片剪切 */
    + (UIImage *)imageClip:(NSString *)imageName {
        UIImage *image = [UIImage imageNamed:imageName];
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
        //剪切
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path addArcWithCenter:CGPointMake(image.size.width * 0.5, image.size.height * 0.5) radius:image.size.width * 0.5 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
        [path addClip];
        // 画图
        [image drawAtPoint:CGPointZero];
        // 获取新图片
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
    

    demo地址

    相关文章

      网友评论

        本文标题:iOS QuartZ 2D 窥探

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