博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)
阅读量:6507 次
发布时间:2019-06-24

本文共 2947 字,大约阅读时间需要 9 分钟。

Stroke-描边

影响描边的因素

  • 线的宽度-CGContextSetLineWidth
  • 交叉线的处理方式-CGContextSetLineJoin
  • 线顶端的处理方式-CGContextSetLineCap
  • 进一步限制交叉线的处理方式 -CGContextSetMiterLimit
  • 是否要虚线-Line dash pattern
  • 颜色控件-CGContextSetStrokeColorSpace
  • 画笔颜色-CGContextSetStrokeColor/CGContextSetStrokeColorWithColor
  • 描边模式-CGContextSetStrokePattern

虚线,画笔颜色,交叉的处理方式,顶端的处理方式,线宽度在之前里有讲过,这里不再赘述。

CGContextSetMiterLimit

如果当前交叉线绘图模式是kCGLineJoinMiter( CGContextSetLineJoin),quartz根据设置的miter值来判断线的join是bevel或者miter。具体的模式是:将miter的长度除以线的宽度,如果小于设置的mitetLimit值,则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,则效果如下

CGContextSetStrokeColorSpace和pattern会在以后的文章详细阐述,这里暂时先略去


Fill-填充

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

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

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

交叉部分比较亮,上层的reverse和下层的reverse相乘,至少和一个一样亮


blend模式较多,这里不一一列举了,参见

你可能感兴趣的文章
javascript-window对象的方法和属性文档大全
查看>>
仿QQ大战—服务器的搭建(ServerSocket)
查看>>
下单快发货慢:一个 JOIN SQL 引起 SqlClient 读取数据慢的奇特问题
查看>>
IIS 6.0/7.0/7.5、Nginx、Apache 等Web Service解析漏洞总结
查看>>
Django 模板之组件、静态文件导入
查看>>
DVWA SQL Injection LOW
查看>>
mysql only_full_group_by
查看>>
Dede 查询附加表
查看>>
如何优雅的拔盘?
查看>>
虚拟机网络设置
查看>>
Google - Largest Sum Submatrix
查看>>
高中数学中需要重点关注的函数和图像
查看>>
兄弟我即将离开上海,手上一些书,送给爱书的人!亲要的速度进!本人只送爱读书的人!不读书者请绕道!契约2年内此书必须转让别人...
查看>>
Idea中使用git
查看>>
文本监控 :oninput onchange onpropertychange 的区别
查看>>
javascript中setInterval与setTimeout中this的问题以及对于闭包的一些理解
查看>>
HDU 1086 You can Solve a Geometry Problem too
查看>>
清除Css中select的下拉箭头样式
查看>>
BZOJ1061 NOI2008 志愿者招募
查看>>
微信分享到朋友圈接口
查看>>