• iOS 2D绘图 (Quartz2D)之路径(stroke,fill,clip,subpath,blend)


    像往常一样 这个系列的博客是跟着大神的脚步来的。按照往例 在此贴出原博客的出处:

    http://blog.csdn.net/hello_hwc?viewmode=list

    我对大神的崇拜之情 如滔滔江水 巴拉巴拉的 .........

    言归正传

    Stroke-描边

    影响描边的因素

    线的宽度-CGContextSetLineWidth

    交叉线的处理方式-CGContextSetLineJoin

    线顶端的处理方式-CGContextSetLineCap

    进一步限制交叉线的处理方式-CGContextSetMiterLimit

    是否要虚线-Line dash Pattern

    颜色控件-CGContextSetStrokeColorSpace

    画笔颜色-CGContextSetStrokeColor/CGContextSetStrokeColorWithColor

    描边模式 -CGContextSetStrokePattern

    虚线 画笔颜色 交叉的处理方式 前面的博客已经讲过,这里就不在赘述了。

    CGContextSetMiterLimit

    如果当前交叉线绘图模式是KCGLineJoinMiter(CGContextSetLineJoin),Quartz 根据设置的miter值来判断线的join是bevel或者miter。
    具体的模式是:将miter的长度除以线的宽度,如果小于设置的miterLimit的值,则join style为bevel;

    先看看join的三种效果

    举个例子可能更加容易明白

    CGContextMoveToPoint(context,10,10);
    CGContextAddLineToPoint(context, 50, 50);
    CGContextAddLineToPoint(context, 10, 90);
    CGContextSetLineWidth(context, 10.0);
    CGContextSetLineJoin(context, kCGLineJoinMiter);
    CGContextSetMiterLimit(context,20.0);
    
    CGContextStrokePath(context);

    效果

    将Miter设置为1 则效果如下:


    Fill 填充

    Quartz填充的时候 会认为subpath是封闭的,然后根据规则来填充,有两种规则

    1>nonzero winding number rule.沿着当前点,画一条直线到区域外,检查交叉点 如果交叉点从左到右 则加一,从右到左,则减去一。如果结果不为0,则绘制。

    2>even-odd rule,沿着当前点,花一条线到区域外,然后检查相交的路径,偶数则绘制,奇数则不绘制。
    具体效果如下

    相关函数

    CGContextEOFillPath-用even-odd rule来填充

    CGContextFillPath - 用nonzero winding number rule方式填充

    CGContextFillRect/CGContextFillRects-填充指定区域内的path

    CGContextFillEllipseInRect-填充椭圆

    CGContextDrawPath-绘制当前Path(根据参数stroke/fill)


    clip- 切割

    顾名思义,根据path只绘制指定的区域,在区域外的都不会绘制。

    举个例子 截取圆形区域

    效果

    注意,切割是和状态相关的,以为这切割以后都是在切割后的context中绘制的。

    如果想要保存状态,要进行压栈和出栈处理

    代码

    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextBeginPath (context);
        CGContextAddArc(context,50, 50,20,0, M_PI * 2,true);
        CGContextClosePath (context);
        CGContextClip (context);
        CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);
        CGContextFillRect(context, rect);
    
        //New Code
        CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
    
        CGContextMoveToPoint(context,10,10);
        CGContextAddLineToPoint(context, 50, 50);
        CGContextAddLineToPoint(context, 10, 90);
    
        CGContextSetLineWidth(context, 10.0);
        CGContextSetLineJoin(context, kCGLineJoinMiter);
        CGContextSetMiterLimit(context,20.0);
        CGContextStrokePath(context);
    }
    -(instancetype)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            self.opaque = NO;
        }
        return self;
    }

    相关函数

    CGContextClip 按照nonzero winding number rule规则切割
    CGContextEOClip 按照even-odd规则切割
    CGContextClipToRect 切割到指定矩形
    CGContextClipToRects 切割到指定矩形组
    CGContextClipToMask 切割到mask

    Subpath - 子路径

    很简单,在stroke/fill或者CGContextBeginPath/CGContextClosePath以后就新开启一个子路径。

    注意:

    CGContextClosePath,会连接第一个点和最后一个点

    Blend 混合模式

    Quartz中,默认的颜色混合模式采用如下公式 
    result = (alpha * foreground) + (1 - alpha) * background

    可以使用CGContextSetBlendMode来设置不同的颜色混合模式,注意设置blend是与context绘制状态相关的,一切与状态相关的设置都要想到状态堆栈

    background

    foreGround

    Normal Blend Mode

     Multiply Blend Mode

    交叉部分会显得比较暗,用上一层和底层相乘,至少和一层一样暗

     

     Screen Blend Mode

  • 相关阅读:
    opencv 基本使用
    opencv 无法使用 dll 动态链接库 UnsatisfiedLinkError java.library.path Can't find dependent libraries
    System.load(String filename)和System.loadLibrary(String libname)的区别
    easyui-combox(tagbox) 多选操作 显示为tagbox
    form表单下的button按钮会自动提交表单的问题
    深夜一次数据库执行SQL思考(怎么看执行报错信息)
    Spring Boot 使用Java代码创建Bean并注册到Spring中
    maven 打jar 被引用后 出现 cannot resolve symbol 错误 生成jar包形式代码文件组织格式 非springboot文件组织格式
    Spring 自动转配类 在类中使用@Bean 注解进行转配但是需要排除该类说明
    EasyUI datagrid columns 中 field 区分大小写
  • 原文地址:https://www.cnblogs.com/huanying2000/p/6226700.html
Copyright © 2020-2023  润新知